mirror of https://github.com/sqlite/sqlite
Improve coverage of pager.c. (CVS 6158)
FossilOrigin-Name: 855c4093cf331496d9ef508011ad814e91e3882f
This commit is contained in:
parent
96c7a7d95f
commit
7cbd589da0
22
manifest
22
manifest
|
@ -1,5 +1,5 @@
|
|||
C Fix\sa\sbug\scaused\sby\soverzealous\scode\stest\scoverage\ssimplifications.\nBug\sfound\sby\sTH3.\s(CVS\s6157)
|
||||
D 2009-01-10T15:34:12
|
||||
C Improve\scoverage\sof\spager.c.\s(CVS\s6158)
|
||||
D 2009-01-10T16:15:09
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 05461a9b5803d5ad10c79f989801e9fd2cc3e592
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
|
@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
|||
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
||||
F src/os_unix.c 7825c6178597713382d74adbf8c8c00ffcdc42d4
|
||||
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
|
||||
F src/pager.c 97bfbacae6131b8d228628803606e98dd763b474
|
||||
F src/pager.c a1e23f2c55bda1303cb6236d4aca9666e58eb610
|
||||
F src/pager.h 9870acb2d653848d90d765d7cbf163496d6c8111
|
||||
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
|
||||
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
|
||||
|
@ -159,7 +159,7 @@ F src/shell.c 65d19f8996a160f288087e31810f24025439c62a
|
|||
F src/sqlite.h.in 6cd2489e40fe97ba58c60044a4ced377e08b6d09
|
||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||
F src/sqliteInt.h 4b2a8eb466c30daa90d25f9d3bb2e85b60ad47af
|
||||
F src/sqliteLimit.h 651a2757ba55aeba1da167786b6a8c3404433940
|
||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||
F src/table.c 23db1e5f27c03160987c122a078b4bb51ef0b2f8
|
||||
F src/tclsqlite.c 4415e1033bd3e92b05a6a9cde911ee4de3b82df9
|
||||
|
@ -288,7 +288,7 @@ F test/crash4.test 02ff4f15c149ca1e88a5c299b4896c84d9450c3b
|
|||
F test/crash5.test 80a2f7073381837fc082435c97df52a830abcd80
|
||||
F test/crash6.test 9c730cf06335003cb1f5cfceddacd044155336e0
|
||||
F test/crash7.test e20a7b9ee1d16eaef7c94a4cb7ed2191b4d05970
|
||||
F test/crash8.test 2ee8ecfed37eea4b987148fe36d6b56175c7d049
|
||||
F test/crash8.test 5b0e499c1dfaa2025e8ab69e4be32f71d4d92b23
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
|
@ -413,7 +413,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
|||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
|
||||
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
|
||||
F test/jrnlmode.test e004a5ed138e06464d74dbd6bead01908f264c52
|
||||
F test/jrnlmode.test a77f95a7cbdc8373582fd274f24124ad0d3a8fb6
|
||||
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 22f7857f9d7da7ff5061ded8806c43a6271109fc
|
||||
|
@ -430,7 +430,7 @@ F test/lock6.test f4e9052b14da3bd6807a757d5aed15c17321031a
|
|||
F test/lookaside.test e69f822f13745f1d5c445c6e30e30f059f30c8e5
|
||||
F test/main.test 187a9a1b5248ed74a83838c581c15ec6023b555b
|
||||
F test/make-where7.tcl 40bb740b37eead343eaf57b74ab72d2a5a304745
|
||||
F test/malloc.test 86f378c52202b5b39b54a7fc560a4a75d77ce4f1
|
||||
F test/malloc.test 95e94f8a3dd1169c8774788ec4148ea032ea20d8
|
||||
F test/malloc3.test 4bc57f850b212f706f3e1b37c4eced1d5a727cd1
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test 20d1a0884b03edf811bfd7005faade028367e7c8
|
||||
|
@ -696,7 +696,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P 2cbea64fb00a1b5b8aa0e9c958b2a09256ae59bc
|
||||
R 7759d6bbe5785c316ce1fcb98ad155c6
|
||||
U drh
|
||||
Z 8f01cd8c083356c8b7a4a4354e84f698
|
||||
P 3da5578726cb22118dfca38a2098a1e378644387
|
||||
R 320ab8e7bd88e5e4d3a0d64f8789cffb
|
||||
U danielk1977
|
||||
Z 43f0761b39243fe434b2dca241a4ad9a
|
||||
|
|
|
@ -1 +1 @@
|
|||
3da5578726cb22118dfca38a2098a1e378644387
|
||||
855c4093cf331496d9ef508011ad814e91e3882f
|
81
src/pager.c
81
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.544 2009/01/09 17:11:05 danielk1977 Exp $
|
||||
** @(#) $Id: pager.c,v 1.545 2009/01/10 16:15:09 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
|
@ -116,6 +116,14 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
|
|||
# define CODEC2(P,D,N,X) ((char*)D)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The maximum allowed sector size. 16MB. If the xSectorsize() method
|
||||
** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
|
||||
** This could conceivably cause corruption following a power failure on
|
||||
** such a system. This is currently an undocumented limit.
|
||||
*/
|
||||
#define MAX_SECTOR_SIZE 0x0100000
|
||||
|
||||
/*
|
||||
** An instance of the following structure is allocated for each active
|
||||
** savepoint and statement transaction in the system. All such structures
|
||||
|
@ -401,7 +409,7 @@ static int jrnlBufferSize(Pager *pPager){
|
|||
|
||||
if( fd->pMethods ){
|
||||
dc = sqlite3OsDeviceCharacteristics(fd);
|
||||
nSector = sqlite3OsSectorSize(fd);
|
||||
nSector = pPager->sectorSize;
|
||||
szPage = pPager->pageSize;
|
||||
}
|
||||
|
||||
|
@ -760,7 +768,8 @@ static int readJournalHdr(
|
|||
int rc;
|
||||
unsigned char aMagic[8]; /* A buffer to hold the magic header */
|
||||
i64 jrnlOff;
|
||||
int iPageSize;
|
||||
u32 iPageSize;
|
||||
u32 iSectorSize;
|
||||
|
||||
seekJournalHdr(pPager);
|
||||
if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
|
||||
|
@ -785,28 +794,41 @@ static int readJournalHdr(
|
|||
rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
|
||||
if( rc ) return rc;
|
||||
|
||||
rc = read32bits(pPager->jfd, jrnlOff+16, (u32 *)&iPageSize);
|
||||
if( rc==SQLITE_OK
|
||||
&& iPageSize>=512
|
||||
&& iPageSize<=SQLITE_MAX_PAGE_SIZE
|
||||
&& ((iPageSize-1)&iPageSize)==0
|
||||
){
|
||||
u16 pagesize = (u16)iPageSize;
|
||||
rc = sqlite3PagerSetPagesize(pPager, &pagesize);
|
||||
}
|
||||
if( rc ) return rc;
|
||||
if( pPager->journalOff==0 ){
|
||||
rc = read32bits(pPager->jfd, jrnlOff+16, &iPageSize);
|
||||
if( rc ) return rc;
|
||||
|
||||
/* Update the assumed sector-size to match the value used by
|
||||
** the process that created this journal. If this journal was
|
||||
** created by a process other than this one, then this routine
|
||||
** is being called from within pager_playback(). The local value
|
||||
** of Pager.sectorSize is restored at the end of that routine.
|
||||
*/
|
||||
rc = read32bits(pPager->jfd, jrnlOff+12, &pPager->sectorSize);
|
||||
if( rc ) return rc;
|
||||
if( (pPager->sectorSize & (pPager->sectorSize-1))!=0
|
||||
|| pPager->sectorSize>0x1000000 ){
|
||||
return SQLITE_DONE;
|
||||
if( iPageSize<512
|
||||
|| iPageSize>SQLITE_MAX_PAGE_SIZE
|
||||
|| ((iPageSize-1)&iPageSize)!=0
|
||||
){
|
||||
/* If the page-size in the journal-header is invalid, then the process
|
||||
** that wrote the journal-header must have crashed before the header
|
||||
** was synced. In this case stop reading the journal file here.
|
||||
*/
|
||||
rc = SQLITE_DONE;
|
||||
}else{
|
||||
u16 pagesize = (u16)iPageSize;
|
||||
rc = sqlite3PagerSetPagesize(pPager, &pagesize);
|
||||
assert( rc!=SQLITE_OK || pagesize==(u16)iPageSize );
|
||||
}
|
||||
if( rc ) return rc;
|
||||
|
||||
/* Update the assumed sector-size to match the value used by
|
||||
** the process that created this journal. If this journal was
|
||||
** created by a process other than this one, then this routine
|
||||
** is being called from within pager_playback(). The local value
|
||||
** of Pager.sectorSize is restored at the end of that routine.
|
||||
*/
|
||||
rc = read32bits(pPager->jfd, jrnlOff+12, &iSectorSize);
|
||||
if( rc ) return rc;
|
||||
if( (iSectorSize&(iSectorSize-1))
|
||||
|| iSectorSize<512
|
||||
|| iSectorSize>MAX_SECTOR_SIZE
|
||||
){
|
||||
return SQLITE_DONE;
|
||||
}
|
||||
pPager->sectorSize = iSectorSize;
|
||||
}
|
||||
|
||||
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
|
||||
|
@ -1503,7 +1525,7 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
|
|||
** Set the sectorSize for the given pager.
|
||||
**
|
||||
** The sector size is at least as big as the sector size reported
|
||||
** by sqlite3OsSectorSize(). The minimum sector size is 512.
|
||||
** by sqlite3OsSectorSize(). The minimum sector size is 512.
|
||||
*/
|
||||
static void setSectorSize(Pager *pPager){
|
||||
assert(pPager->fd->pMethods||pPager->tempFile);
|
||||
|
@ -1517,6 +1539,9 @@ static void setSectorSize(Pager *pPager){
|
|||
if( pPager->sectorSize<512 ){
|
||||
pPager->sectorSize = 512;
|
||||
}
|
||||
if( pPager->sectorSize>MAX_SECTOR_SIZE ){
|
||||
pPager->sectorSize = MAX_SECTOR_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2022,9 +2047,9 @@ int sqlite3PagerOpen(
|
|||
** + The largest page size that can be written atomically.
|
||||
*/
|
||||
if( rc==SQLITE_OK && !readOnly ){
|
||||
int iSectorSize = sqlite3OsSectorSize(pPager->fd);
|
||||
if( szPageDflt<iSectorSize ){
|
||||
szPageDflt = iSectorSize;
|
||||
setSectorSize(pPager);
|
||||
if( szPageDflt<pPager->sectorSize ){
|
||||
szPageDflt = pPager->sectorSize;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
**
|
||||
** This file defines various limits of what SQLite can process.
|
||||
**
|
||||
** @(#) $Id: sqliteLimit.h,v 1.9 2009/01/07 16:15:43 danielk1977 Exp $
|
||||
** @(#) $Id: sqliteLimit.h,v 1.10 2009/01/10 16:15:09 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -130,6 +130,13 @@
|
|||
/* Maximum page size. The upper bound on this value is 32768. This a limit
|
||||
** imposed by the necessity of storing the value in a 2-byte unsigned integer
|
||||
** and the fact that the page size must be a power of 2.
|
||||
**
|
||||
** If this limit is changed, then the compiled library is technically
|
||||
** incompatible with an SQLite library compiled with a different limit. If
|
||||
** a process operating on a database with a page-size of 65536 bytes
|
||||
** crashes, then an instance of SQLite compiled with the default page-size
|
||||
** limit will not be able to rollback the aborted transaction. This could
|
||||
** lead to database corruption.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_PAGE_SIZE
|
||||
# define SQLITE_MAX_PAGE_SIZE 32768
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# Later: Also, some other specific scenarios required for coverage
|
||||
# testing that do not lead to corruption.
|
||||
#
|
||||
# $Id: crash8.test,v 1.2 2009/01/09 10:49:14 danielk1977 Exp $
|
||||
# $Id: crash8.test,v 1.3 2009/01/10 16:15:09 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
@ -118,13 +118,27 @@ proc read_file {zFile} {
|
|||
close $fd
|
||||
return $zData
|
||||
}
|
||||
proc write_file {zFile zData} {
|
||||
set fd [open $zFile w]
|
||||
fconfigure $fd -translation binary
|
||||
puts -nonewline $fd $zData
|
||||
close $fd
|
||||
}
|
||||
|
||||
# The following tests check that SQLite will not roll back a hot-journal
|
||||
# file if the sector-size field in the first journal file header is
|
||||
# suspect. Definition of suspect:
|
||||
#
|
||||
# a) Not a power of 2, or (crash8-3.5)
|
||||
# b) Greater than 0x01000000 (16MB), or (crash8-3.6)
|
||||
# c) Less than 512. (crash8-3.7)
|
||||
#
|
||||
# Also test that SQLite will not rollback a hot-journal file with a
|
||||
# suspect page-size. In this case "suspect" means:
|
||||
#
|
||||
# a) Not a power of 2, or
|
||||
# b) Greater than 0x1000000 (16MB).
|
||||
# b) Less than 512, or
|
||||
# c) Greater than SQLITE_MAX_PAGE_SIZE
|
||||
#
|
||||
do_test crash8-3.1 {
|
||||
list [file exists test.db-joural] [file exists test.db]
|
||||
|
@ -148,34 +162,61 @@ do_test crash8-3.4 {
|
|||
binary scan [string range $zJournal 20 23] I nSector
|
||||
set nSector
|
||||
} {512}
|
||||
|
||||
do_test crash8-3.5 {
|
||||
set zJournal2 [
|
||||
string replace $zJournal 20 23 [binary format I 511]
|
||||
]
|
||||
set fd [open test.db-journal w]
|
||||
fconfigure $fd -translation binary
|
||||
puts -nonewline $fd $zJournal2
|
||||
close $fd
|
||||
|
||||
set zJournal2 [string replace $zJournal 20 23 [binary format I 513]]
|
||||
write_file test.db-journal $zJournal2
|
||||
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check
|
||||
}
|
||||
} {0 ok}
|
||||
do_test crash8-3.6 {
|
||||
set zJournal2 [
|
||||
string replace $zJournal 20 23 [binary format I [expr 0x2000000]]
|
||||
]
|
||||
set fd [open test.db-journal w]
|
||||
fconfigure $fd -translation binary
|
||||
puts -nonewline $fd $zJournal2
|
||||
close $fd
|
||||
set zJournal2 [string replace $zJournal 20 23 [binary format I 0x2000000]]
|
||||
write_file test.db-journal $zJournal2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check
|
||||
}
|
||||
} {0 ok}
|
||||
do_test crash8-3.7 {
|
||||
set zJournal2 [string replace $zJournal 20 23 [binary format I 256]]
|
||||
write_file test.db-journal $zJournal2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check
|
||||
}
|
||||
} {0 ok}
|
||||
|
||||
do_test crash8-3.8 {
|
||||
set zJournal2 [string replace $zJournal 24 27 [binary format I 513]]
|
||||
write_file test.db-journal $zJournal2
|
||||
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check
|
||||
}
|
||||
} {0 ok}
|
||||
do_test crash8-3.9 {
|
||||
set big [expr $SQLITE_MAX_PAGE_SIZE * 2]
|
||||
set zJournal2 [string replace $zJournal 24 27 [binary format I $big]]
|
||||
write_file test.db-journal $zJournal2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check
|
||||
}
|
||||
} {0 ok}
|
||||
do_test crash8-3.10 {
|
||||
set zJournal2 [string replace $zJournal 24 27 [binary format I 256]]
|
||||
write_file test.db-journal $zJournal2
|
||||
execsql {
|
||||
SELECT count(*) FROM t1;
|
||||
PRAGMA integrity_check
|
||||
}
|
||||
} {0 ok}
|
||||
|
||||
do_test crash8-3.11 {
|
||||
set fd [open test.db-journal w]
|
||||
fconfigure $fd -translation binary
|
||||
puts -nonewline $fd $zJournal
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# This file implements regression tests for SQLite library. The focus
|
||||
# of these tests is the journal mode pragma.
|
||||
#
|
||||
# $Id: jrnlmode.test,v 1.10 2009/01/09 10:49:14 danielk1977 Exp $
|
||||
# $Id: jrnlmode.test,v 1.11 2009/01/10 16:15:09 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -419,6 +419,23 @@ ifcapable pragma {
|
|||
set sz [file size test.db-journal]
|
||||
expr {$sz>=$journalsize}
|
||||
} {1}
|
||||
|
||||
# Test a size-limit of 0.
|
||||
#
|
||||
do_test jrnlmode-5.20 {
|
||||
execsql {
|
||||
PRAGMA journal_size_limit = 0;
|
||||
BEGIN;
|
||||
UPDATE t1 SET a = randomblob(1000);
|
||||
}
|
||||
} {0}
|
||||
do_test jrnlmode-5.21 {
|
||||
expr {[file size test.db-journal] > 1024}
|
||||
} {1}
|
||||
do_test jrnlmode-5.22 {
|
||||
execsql COMMIT
|
||||
list [file exists test.db-journal] [file size test.db-journal]
|
||||
} {1 0}
|
||||
}
|
||||
|
||||
ifcapable pragma {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# to see what happens in the library if a malloc were to really fail
|
||||
# due to an out-of-memory situation.
|
||||
#
|
||||
# $Id: malloc.test,v 1.72 2009/01/10 11:13:40 danielk1977 Exp $
|
||||
# $Id: malloc.test,v 1.73 2009/01/10 16:15:09 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -678,7 +678,7 @@ do_malloc_test 29 -sqlprep {
|
|||
INSERT INTO t1 SELECT * FROM t1 UNION ALL SELECT * FROM t1;
|
||||
}
|
||||
|
||||
do_malloc_test 29 -tclprep {
|
||||
do_malloc_test 30 -tclprep {
|
||||
db eval {
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES(randstr(500,500));
|
||||
|
@ -708,6 +708,18 @@ do_malloc_test 29 -tclprep {
|
|||
SELECT * FROM t1 ORDER BY x;
|
||||
}
|
||||
|
||||
# After committing a transaction in persistent-journal mode, if a journal
|
||||
# size limit is configured SQLite may attempt to truncate the journal file.
|
||||
# This test verifies the libraries response to a malloc() failure during
|
||||
# this operation.
|
||||
#
|
||||
do_malloc_test 31 -sqlprep {
|
||||
PRAGMA journal_mode = persist;
|
||||
PRAGMA journal_size_limit = 1024;
|
||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||
} -sqlbody {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
|
||||
# Ensure that no file descriptors were leaked.
|
||||
do_test malloc-99.X {
|
||||
|
|
Loading…
Reference in New Issue