-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
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
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
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
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
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
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
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
-a461988661368bce799ef3d498a18e88559e14c7
\ No newline at end of file
+8ced491588764b1e1066787d0abf3cde8b60970b
\ No newline at end of file
** 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
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 */
};
/*
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 */
/* 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 ){
** 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 ){
** 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;
pCur->isValid ? "" : " eof"
);
}
+#endif
}
#endif
pCur->pPrev = 0;
pBt->pCursor = pCur;
pCur->isValid = 0;
- pCur->status = SQLITE_OK;
*ppCur = pCur;
return SQLITE_OK;
** 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 );
** 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);
*/
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 ){
*/
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 ){
*/
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 );
#endif
if( rc ){
releasePage(pToRelease);
- clearCell(pPage, pCell);
+ /* clearCell(pPage, pCell); */
return rc;
}
put4byte(pPrior, pgnoOvfl);
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;
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;
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;
if( !pPage->leaf ){
pgnoChild = get4byte(pCell);
}
- clearCell(pPage, pCell);
+ rc = clearCell(pPage, pCell);
+ if( rc ) return rc;
if( !pPage->leaf ){
/*
/* 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
** 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;
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
** 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"
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? ***/
*************************************************************************
** 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"
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 */
** 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"
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;
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;
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;
}
--- /dev/null
+# 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
+
+
+
--- /dev/null
+# 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
+
+
# 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]
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
#
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}
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.
#
# 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
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
} {}
# 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]
set L [btree_data $::c2]
set LM1 [expr {$L-1}]
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 {$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 {$k!=$i} {
return "Key $i is missing from both foreground and background"
btree_delete $::c3
} else {
if {$c<0} {btree_next $::c3}
- if {[string match $basekey* [btree_key $::c3]]} {
- btree_delete $::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 {[string match $basekey* [btree_key $::c4]]} {
- btree_delete $::c4
+ if {![btree_eof $::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} {
btree_delete $::c4
}
--- /dev/null
+# 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
+
# 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
}
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