mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Merge experimental changes into trunk.
FossilOrigin-Name: aa092ac928dc19bd356d25a1dfd3f432dc145ce6
This commit is contained in:
50
manifest
50
manifest
@@ -1,5 +1,5 @@
|
||||
C Changes\sto\sdebugging\scode\sin\smutex_unix.c\sand\smutex_w32.c\sto\smake\san\sassert()\sstatement\sthreadsafe.
|
||||
D 2010-08-10T07:12:27
|
||||
C Merge\sexperimental\schanges\sinto\strunk.
|
||||
D 2010-08-11T06:04:19
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -154,9 +154,9 @@ F src/os.c 60178f518c4d6c0dcb59f7292232281d7bea2dcf
|
||||
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
|
||||
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
||||
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
||||
F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248
|
||||
F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
|
||||
F src/pager.c 202e3dcb3f36c858d4339c0f6fa3d04d67258127
|
||||
F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
|
||||
F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
|
||||
F src/pager.c b3db762350ee71f5f8bde04f21ca2ffcccded483
|
||||
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
|
||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
|
||||
@@ -170,14 +170,14 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c 4b8f481406c7fd2672abf715a2acaed8f9cde046
|
||||
F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
|
||||
F src/sqlite.h.in 1d29cd776795b0daa925fa5e8082ad79ba8e4ac4
|
||||
F src/sqlite.h.in 2d72a6242df41c517e38eec8791abcf5484a36f1
|
||||
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
||||
F src/sqliteInt.h e33b15e8176442bf7484f0e716edfd1ce03b2979
|
||||
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
|
||||
F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c 5cd96419fb6c771006f064196ccc70c29d01bec7
|
||||
F src/test1.c ff3b4533fc4d78d1bff2ef831a5791db55096ed3
|
||||
F src/test1.c 0bfcda72f9f8ab5c0e90fac05cc22c1c21131ddf
|
||||
F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
|
||||
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
|
||||
F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee
|
||||
@@ -198,16 +198,16 @@ F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2
|
||||
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
|
||||
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
||||
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
|
||||
F src/test_journal.c 424a334cdfdc8a6f975abe3641440147bded3185
|
||||
F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
F src/test_malloc.c 058e41dc853b1fa8ccd1083e9571018a74aeb3a7
|
||||
F src/test_malloc.c 09a88f0c111201dc4f8c20470aa1b5f611d59200
|
||||
F src/test_mutex.c ce06b59aca168cd8c520b77159a24352a7469bd3
|
||||
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
|
||||
F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c
|
||||
F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8
|
||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
|
||||
F src/test_stat.c 6ebaf2a86d01ccda24e49c148f1d33e8badda06e
|
||||
F src/test_stat.c dcabb7d39da058cbfc9ddc427cd92fbf14822b28
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
|
||||
F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234
|
||||
@@ -227,8 +227,8 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
|
||||
F src/vdbemem.c e5673f81a2381b35c60e73ef0a8502be2ab1041e
|
||||
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
||||
F src/vtab.c 82200af3881fa4e1c9cf07cf31d98c09d437e3ab
|
||||
F src/wal.c 0925601f3299c2941a67c9cfff41ee710f70ca82
|
||||
F src/wal.h 906c85760598b18584921fe08008435aa4eeeeb2
|
||||
F src/wal.c 582acbaa606c748675fafff516ec1b34a7bdae62
|
||||
F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c
|
||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||
F src/where.c 7db3e41c2a846f9deeb24f1bbb75461b4010b7b5
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -241,7 +241,7 @@ F test/alter4.test 9386ffd1e9c7245f43eca412b2058d747509cc1f
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/analyze.test bf692e7db414f268a136bade16c03a1bdbb9240c
|
||||
F test/analyze2.test 59dac6c399c0c5d1a90a11ee7cc606743fb6db93
|
||||
F test/analyze3.test 535bf0762f49fa96885efe8568738276c2204a2a
|
||||
F test/analyze3.test 6d4f4b0929545a9d1af803a0608a0c51b92a3537
|
||||
F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3
|
||||
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
|
||||
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
|
||||
@@ -330,7 +330,7 @@ F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/date.test 6354b883f922c38046a8efbad187cc95df6da023
|
||||
F test/dbstatus.test f3c88a3f8d15716e6ae73567a78ee96420c294a3
|
||||
F test/dbstatus.test ba072efbd7fcbeb4da324bfbdf1e596d994c159e
|
||||
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
|
||||
F test/delete.test f7629d9eb245dfca170169cc5c7a735dec34aeb4
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -347,10 +347,11 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
|
||||
F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
|
||||
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
||||
F test/exclusive.test 5fe18e10a159342dd52ca14b1554e33f98734267
|
||||
F test/exclusive.test b1f9012cabc124af947165d15ffa62ad20f63db8
|
||||
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
|
||||
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
|
||||
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
||||
F test/filefmt.test f77c92141960b7933bc6691631d2ad62257ef40a
|
||||
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
|
||||
@@ -470,7 +471,7 @@ F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901
|
||||
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
|
||||
F test/journal2.test 50a3604768494d4a337f194f0a9480e7c57dcb72
|
||||
F test/journal3.test ff175219be1b02d2f7e54297ad7e491b7533edb6
|
||||
F test/jrnlmode.test 2d5a8b6d68de8512f522532731d90ca96912f3b7
|
||||
F test/jrnlmode.test e3fe6c4a2c3213d285650dc8e33aab7eaaa5ce53
|
||||
F test/jrnlmode2.test a19e28de1a6ec898067e46a122f1b71c9323bf00
|
||||
F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710
|
||||
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
|
||||
@@ -540,13 +541,14 @@ F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
|
||||
F test/pager1.test d8e4b2bc8164c920e6ea0572c9e13576d6e4f3fa
|
||||
F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef
|
||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||
F test/pagerfault.test c1d176326ce244db157ce9c3ba128be2a9b172d6
|
||||
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
|
||||
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
|
||||
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
|
||||
F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d
|
||||
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
|
||||
F test/permutations.test 3fe47c21c32b294b2354e702a25bfbff65747bb1
|
||||
F test/permutations.test 17498d1219f922d5a6da893a94c4dc7766fb2426
|
||||
F test/pragma.test ed78d200f65c6998df51196cb8c39d5300570f24
|
||||
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
||||
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
|
||||
@@ -630,7 +632,7 @@ F test/thread2.test e08034b83fe9693ade77049732518e5b3d2d700d
|
||||
F test/thread_common.tcl 2aa6f2fdcd4d6e461169c3e5ca098eebf643b863
|
||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||
F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
|
||||
F test/threadtest3.c f7e21a9bcddff1499d46a1fc68d1ba31e4063be4
|
||||
F test/threadtest3.c 58df1e3c060f534fd7fb0702331b0acc41c381d8
|
||||
F test/tkt-02a8e81d44.test 58494de77be2cf249228ada3f313fa399821c6ab
|
||||
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
|
||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||
@@ -781,8 +783,8 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
|
||||
F test/wal.test 1891e6f72dd437a1c2a48091aa9182ba17a8f780
|
||||
F test/wal2.test 8dcebda41587e0b2b57194d03fd8700e01e85656
|
||||
F test/wal3.test d2ae7e66f973bd6b58ce49e546b2c00f44fe0485
|
||||
F test/wal2.test 223f3e14d475730af772a7f5862d4bcfa7565c3a
|
||||
F test/wal3.test 695ea0f6c516423c611891df9a285aacd33344e3
|
||||
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
|
||||
F test/wal_common.tcl 895d76138043b86bdccf36494054bdabcf65837b
|
||||
F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
|
||||
@@ -792,7 +794,7 @@ F test/walcrash.test e763841551d6b23677ccb419797c1589dcbdbaf5
|
||||
F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
|
||||
F test/walfault.test 05c470688d742688e455dd56816bd6bcffa298f8
|
||||
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
|
||||
F test/walmode.test 5dc3008ef71988ecdd949ea16e5750e325b92b54
|
||||
F test/walmode.test 4ecd37284f245247f7935896ab66f6943f0432a0
|
||||
F test/walshared.test 985b4a3406b2b2dace1d52a42d26a11dd6900981
|
||||
F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
|
||||
F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c
|
||||
@@ -841,7 +843,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 9cebaf2dca6dc35e489537fe7c55474e1029a98e
|
||||
R da77b0ae4e15ab90a6a323c7de4ca438
|
||||
P e82e32bd431ccacd276df8241592eb5519d87122 42ba43ac690dc800fb8b969ae257a79942918342
|
||||
R 905d488f0b9b28e6cb7ddb8f6f378b5f
|
||||
U dan
|
||||
Z ef5f61caa72edd66e82b2e19ff2bf16a
|
||||
Z cd4d4135a3c0d3f56327a6ac460d7792
|
||||
|
||||
@@ -1 +1 @@
|
||||
e82e32bd431ccacd276df8241592eb5519d87122
|
||||
aa092ac928dc19bd356d25a1dfd3f432dc145ce6
|
||||
@@ -210,6 +210,7 @@ struct unixFile {
|
||||
int fileFlags; /* Miscellanous flags */
|
||||
const char *zPath; /* Name of the file */
|
||||
unixShm *pShm; /* Shared memory segment information */
|
||||
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
int openFlags; /* The flags specified at open() */
|
||||
#endif
|
||||
@@ -2763,6 +2764,7 @@ static int unixWrite(
|
||||
}
|
||||
SimulateIOError(( wrote=(-1), amt=1 ));
|
||||
SimulateDiskfullError(( wrote=0, amt=1 ));
|
||||
|
||||
if( amt>0 ){
|
||||
if( wrote<0 ){
|
||||
/* lastErrno set by seekAndWrite */
|
||||
@@ -2772,6 +2774,7 @@ static int unixWrite(
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -2973,12 +2976,23 @@ static int unixSync(sqlite3_file *id, int flags){
|
||||
** Truncate an open file to a specified size
|
||||
*/
|
||||
static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||
unixFile *pFile = (unixFile *)id;
|
||||
int rc;
|
||||
assert( id );
|
||||
assert( pFile );
|
||||
SimulateIOError( return SQLITE_IOERR_TRUNCATE );
|
||||
rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
|
||||
|
||||
/* If the user has configured a chunk-size for this file, truncate the
|
||||
** file so that it consists of an integer number of chunks (i.e. the
|
||||
** actual file size after the operation may be larger than the requested
|
||||
** size).
|
||||
*/
|
||||
if( pFile->szChunk ){
|
||||
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
|
||||
}
|
||||
|
||||
rc = ftruncate(pFile->h, (off_t)nByte);
|
||||
if( rc ){
|
||||
((unixFile*)id)->lastErrno = errno;
|
||||
pFile->lastErrno = errno;
|
||||
return SQLITE_IOERR_TRUNCATE;
|
||||
}else{
|
||||
#ifndef NDEBUG
|
||||
@@ -2989,8 +3003,8 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||
** when restoring a database using the backup API from a zero-length
|
||||
** source.
|
||||
*/
|
||||
if( ((unixFile*)id)->inNormalWrite && nByte==0 ){
|
||||
((unixFile*)id)->transCntrChng = 1;
|
||||
if( pFile->inNormalWrite && nByte==0 ){
|
||||
pFile->transCntrChng = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3033,6 +3047,54 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
|
||||
static int proxyFileControl(sqlite3_file*,int,void*);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
|
||||
** file-control operation.
|
||||
**
|
||||
** If the user has configured a chunk-size for this file, it could be
|
||||
** that the file needs to be extended at this point. Otherwise, the
|
||||
** SQLITE_FCNTL_SIZE_HINT operation is a no-op for Unix.
|
||||
*/
|
||||
static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
||||
if( pFile->szChunk ){
|
||||
i64 nSize; /* Required file size */
|
||||
struct stat buf; /* Used to hold return values of fstat() */
|
||||
|
||||
if( fstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
|
||||
|
||||
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
|
||||
if( nSize>(i64)buf.st_size ){
|
||||
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
|
||||
if( posix_fallocate(pFile->h, buf.st_size, nSize-buf.st_size) ){
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}
|
||||
#else
|
||||
/* If the OS does not have posix_fallocate(), fake it. First use
|
||||
** ftruncate() to set the file size, then write a single byte to
|
||||
** the last byte in each block within the extended region. This
|
||||
** is the same technique used by glibc to implement posix_fallocate()
|
||||
** on systems that do not have a real fallocate() system call.
|
||||
*/
|
||||
int nBlk = buf.st_blksize; /* File-system block size */
|
||||
i64 iWrite; /* Next offset to write to */
|
||||
int nWrite; /* Return value from seekAndWrite() */
|
||||
|
||||
if( ftruncate(pFile->h, nSize) ){
|
||||
pFile->lastErrno = errno;
|
||||
return SQLITE_IOERR_TRUNCATE;
|
||||
}
|
||||
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
|
||||
do {
|
||||
nWrite = seekAndWrite(pFile, iWrite, "", 1);
|
||||
iWrite += nBlk;
|
||||
} while( nWrite==1 && iWrite<nSize );
|
||||
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Information and control of an open file handle.
|
||||
@@ -3047,14 +3109,13 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
*(int*)pArg = ((unixFile*)id)->lastErrno;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_SIZE_HINT: {
|
||||
#if 0 /* No performance advantage seen on Linux */
|
||||
sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
ftruncate(pFile->h, szFile);
|
||||
#endif
|
||||
case SQLITE_FCNTL_CHUNK_SIZE: {
|
||||
((unixFile*)id)->szChunk = *(int *)pArg;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_SIZE_HINT: {
|
||||
return fcntlSizeHint((unixFile *)id, *(i64 *)pArg);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
/* The pager calls this method to signal that it has done
|
||||
** a rollback and that the database is therefore unchanged and
|
||||
|
||||
160
src/os_win.c
160
src/os_win.c
@@ -108,6 +108,7 @@ struct winFile {
|
||||
DWORD sectorSize; /* Sector size of the device file is on */
|
||||
winShm *pShm; /* Instance of shared memory on this file */
|
||||
const char *zPath; /* Full pathname of this file */
|
||||
int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */
|
||||
#if SQLITE_OS_WINCE
|
||||
WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
|
||||
HANDLE hMutex; /* Mutex used to control access to shared lock */
|
||||
@@ -620,6 +621,42 @@ static BOOL winceLockFileEx(
|
||||
** by the sqlite3_io_methods object.
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
** Some microsoft compilers lack this definition.
|
||||
*/
|
||||
#ifndef INVALID_SET_FILE_POINTER
|
||||
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Move the current position of the file handle passed as the first
|
||||
** argument to offset iOffset within the file. If successful, return 0.
|
||||
** Otherwise, set pFile->lastErrno and return non-zero.
|
||||
*/
|
||||
static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
|
||||
LONG upperBits; /* Most sig. 32 bits of new offset */
|
||||
LONG lowerBits; /* Least sig. 32 bits of new offset */
|
||||
DWORD dwRet; /* Value returned by SetFilePointer() */
|
||||
|
||||
upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
|
||||
lowerBits = (LONG)(iOffset & 0xffffffff);
|
||||
|
||||
/* API oddity: If successful, SetFilePointer() returns a dword
|
||||
** containing the lower 32-bits of the new file-offset. Or, if it fails,
|
||||
** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
|
||||
** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
|
||||
** whether an error has actually occured, it is also necessary to call
|
||||
** GetLastError().
|
||||
*/
|
||||
dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a file.
|
||||
**
|
||||
@@ -662,13 +699,6 @@ static int winClose(sqlite3_file *id){
|
||||
return rc ? SQLITE_OK : SQLITE_IOERR;
|
||||
}
|
||||
|
||||
/*
|
||||
** Some microsoft compilers lack this definition.
|
||||
*/
|
||||
#ifndef INVALID_SET_FILE_POINTER
|
||||
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Read data from a file into a buffer. Return SQLITE_OK if all
|
||||
** bytes were read successfully and SQLITE_IOERR if anything goes
|
||||
@@ -680,32 +710,27 @@ static int winRead(
|
||||
int amt, /* Number of bytes to read */
|
||||
sqlite3_int64 offset /* Begin reading at this offset */
|
||||
){
|
||||
LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
|
||||
LONG lowerBits = (LONG)(offset & 0xffffffff);
|
||||
DWORD rc;
|
||||
winFile *pFile = (winFile*)id;
|
||||
DWORD error;
|
||||
DWORD got;
|
||||
winFile *pFile = (winFile*)id; /* file handle */
|
||||
DWORD nRead; /* Number of bytes actually read from file */
|
||||
|
||||
assert( id!=0 );
|
||||
SimulateIOError(return SQLITE_IOERR_READ);
|
||||
OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
|
||||
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
|
||||
pFile->lastErrno = error;
|
||||
|
||||
if( seekWinFile(pFile, offset) ){
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
|
||||
if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
return SQLITE_IOERR_READ;
|
||||
}
|
||||
if( got==(DWORD)amt ){
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
if( nRead<(DWORD)amt ){
|
||||
/* Unread parts of the buffer must be zero-filled */
|
||||
memset(&((char*)pBuf)[got], 0, amt-got);
|
||||
memset(&((char*)pBuf)[nRead], 0, amt-nRead);
|
||||
return SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -713,47 +738,42 @@ static int winRead(
|
||||
** or some other error code on failure.
|
||||
*/
|
||||
static int winWrite(
|
||||
sqlite3_file *id, /* File to write into */
|
||||
const void *pBuf, /* The bytes to be written */
|
||||
int amt, /* Number of bytes to write */
|
||||
sqlite3_int64 offset /* Offset into the file to begin writing at */
|
||||
sqlite3_file *id, /* File to write into */
|
||||
const void *pBuf, /* The bytes to be written */
|
||||
int amt, /* Number of bytes to write */
|
||||
sqlite3_int64 offset /* Offset into the file to begin writing at */
|
||||
){
|
||||
LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
|
||||
LONG lowerBits = (LONG)(offset & 0xffffffff);
|
||||
DWORD rc;
|
||||
winFile *pFile = (winFile*)id;
|
||||
DWORD error;
|
||||
DWORD wrote = 0;
|
||||
int rc; /* True if error has occured, else false */
|
||||
winFile *pFile = (winFile*)id; /* File handle */
|
||||
|
||||
assert( id!=0 );
|
||||
assert( amt>0 );
|
||||
assert( pFile );
|
||||
SimulateIOError(return SQLITE_IOERR_WRITE);
|
||||
SimulateDiskfullError(return SQLITE_FULL);
|
||||
|
||||
OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
|
||||
rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
|
||||
pFile->lastErrno = error;
|
||||
if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
|
||||
return SQLITE_FULL;
|
||||
}else{
|
||||
return SQLITE_IOERR_WRITE;
|
||||
|
||||
rc = seekWinFile(pFile, offset);
|
||||
if( rc==0 ){
|
||||
u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
|
||||
int nRem = amt; /* Number of bytes yet to be written */
|
||||
DWORD nWrite; /* Bytes written by each WriteFile() call */
|
||||
|
||||
while( nRem>0 && WriteFile(pFile->h, aRem, nRem, &nWrite, 0) && nWrite>0 ){
|
||||
aRem += nWrite;
|
||||
nRem -= nWrite;
|
||||
}
|
||||
if( nRem>0 ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
assert( amt>0 );
|
||||
while(
|
||||
amt>0
|
||||
&& (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
|
||||
&& wrote>0
|
||||
){
|
||||
amt -= wrote;
|
||||
pBuf = &((char*)pBuf)[wrote];
|
||||
}
|
||||
if( !rc || amt>(int)wrote ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
|
||||
if( rc ){
|
||||
if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
|
||||
return SQLITE_FULL;
|
||||
}else{
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -762,26 +782,32 @@ static int winWrite(
|
||||
** Truncate an open file to a specified size
|
||||
*/
|
||||
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
|
||||
LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
|
||||
LONG lowerBits = (LONG)(nByte & 0xffffffff);
|
||||
DWORD dwRet;
|
||||
winFile *pFile = (winFile*)id;
|
||||
DWORD error;
|
||||
int rc = SQLITE_OK;
|
||||
winFile *pFile = (winFile*)id; /* File handle object */
|
||||
int rc = SQLITE_OK; /* Return code for this function */
|
||||
|
||||
assert( pFile );
|
||||
|
||||
assert( id!=0 );
|
||||
OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
|
||||
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
|
||||
dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
if( dwRet==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
|
||||
pFile->lastErrno = error;
|
||||
|
||||
/* If the user has configured a chunk-size for this file, truncate the
|
||||
** file so that it consists of an integer number of chunks (i.e. the
|
||||
** actual file size after the operation may be larger than the requested
|
||||
** size).
|
||||
*/
|
||||
if( pFile->szChunk ){
|
||||
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
|
||||
}
|
||||
|
||||
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
|
||||
if( seekWinFile(pFile, nByte) ){
|
||||
rc = SQLITE_IOERR_TRUNCATE;
|
||||
/* SetEndOfFile will fail if nByte is negative */
|
||||
}else if( !SetEndOfFile(pFile->h) ){
|
||||
}else if( 0==SetEndOfFile(pFile->h) ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
rc = SQLITE_IOERR_TRUNCATE;
|
||||
}
|
||||
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc==SQLITE_OK ? "ok" : "failed"));
|
||||
|
||||
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1146,6 +1172,10 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
*(int*)pArg = (int)((winFile*)id)->lastErrno;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_CHUNK_SIZE: {
|
||||
((winFile*)id)->szChunk = *(int *)pArg;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_SIZE_HINT: {
|
||||
sqlite3_int64 sz = *(sqlite3_int64*)pArg;
|
||||
SimulateIOErrorBenign(1);
|
||||
|
||||
2213
src/pager.c
2213
src/pager.c
File diff suppressed because it is too large
Load Diff
@@ -690,12 +690,21 @@ struct sqlite3_io_methods {
|
||||
** is often close. The underlying VFS might choose to preallocate database
|
||||
** file space based on this hint in order to help writes to the database
|
||||
** file run faster.
|
||||
**
|
||||
** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
|
||||
** extends and truncates the database file in chunks of a size specified
|
||||
** by the user. The fourth argument to [sqlite3_file_control()] should
|
||||
** point to an integer (type int) containing the new chunk-size to use
|
||||
** for the nominated database. Allocating database file space in large
|
||||
** chunks (say 1MB at a time), may reduce file-system fragmentation and
|
||||
** improve performance on some systems.
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
#define SQLITE_GET_LOCKPROXYFILE 2
|
||||
#define SQLITE_SET_LOCKPROXYFILE 3
|
||||
#define SQLITE_LAST_ERRNO 4
|
||||
#define SQLITE_FCNTL_SIZE_HINT 5
|
||||
#define SQLITE_FCNTL_CHUNK_SIZE 6
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle
|
||||
|
||||
39
src/test1.c
39
src/test1.c
@@ -4613,6 +4613,44 @@ static int file_control_lasterrno_test(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_chunksize_test DB DBNAME SIZE
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
|
||||
** SQLITE_SET_LOCKPROXYFILE verbs.
|
||||
*/
|
||||
static int file_control_chunksize_test(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
int nSize; /* New chunk size */
|
||||
char *zDb; /* Db name ("main", "temp" etc.) */
|
||||
sqlite3 *db; /* Database handle */
|
||||
int rc; /* file_control() return code */
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
|
||||
|| Tcl_GetIntFromObj(interp, objv[3], &nSize)
|
||||
){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zDb = Tcl_GetString(objv[2]);
|
||||
if( zDb[0]=='\0' ) zDb = NULL;
|
||||
|
||||
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
|
||||
if( rc ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_lockproxy_test DB PWD
|
||||
**
|
||||
@@ -5106,6 +5144,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "file_control_test", file_control_test, 0 },
|
||||
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
|
||||
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
|
||||
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
|
||||
{ "sqlite3_vfs_list", vfs_list, 0 },
|
||||
|
||||
/* Functions from os.h */
|
||||
|
||||
@@ -361,6 +361,7 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){
|
||||
sqlite3_file *p = pMain->pReal;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
closeTransaction(pMain);
|
||||
aData = sqlite3_malloc(pMain->nPagesize);
|
||||
pMain->pWritable = sqlite3BitvecCreate(pMain->nPage);
|
||||
pMain->aCksum = sqlite3_malloc(sizeof(u32) * (pMain->nPage + 1));
|
||||
@@ -379,6 +380,15 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){
|
||||
** leaf to the jt_file.pWritable bitvec.
|
||||
*/
|
||||
rc = sqlite3OsRead(p, aData, pMain->nPagesize, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
u32 nDbsize = decodeUint32(&aData[28]);
|
||||
if( nDbsize>0 && memcmp(&aData[24], &aData[92], 4)==0 ){
|
||||
u32 iPg;
|
||||
for(iPg=nDbsize+1; iPg<=pMain->nPage; iPg++){
|
||||
sqlite3BitvecSet(pMain->pWritable, iPg);
|
||||
}
|
||||
}
|
||||
}
|
||||
iTrunk = decodeUint32(&aData[32]);
|
||||
while( rc==SQLITE_OK && iTrunk>0 ){
|
||||
u32 nLeaf;
|
||||
@@ -492,7 +502,6 @@ finish_rjf:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Write data to an jt-file.
|
||||
*/
|
||||
|
||||
@@ -728,7 +728,10 @@ static int test_memdebug_settitle(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#define MALLOC_LOG_FRAMES 10
|
||||
#define MALLOC_LOG_FRAMES 10
|
||||
#define MALLOC_LOG_KEYINTS ( \
|
||||
10 * ((sizeof(int)>=sizeof(void*)) ? 1 : sizeof(void*)/sizeof(int)) \
|
||||
)
|
||||
static Tcl_HashTable aMallocLog;
|
||||
static int mallocLogEnabled = 0;
|
||||
|
||||
@@ -745,8 +748,8 @@ static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
|
||||
Tcl_HashEntry *pEntry;
|
||||
int isNew;
|
||||
|
||||
int aKey[MALLOC_LOG_FRAMES];
|
||||
int nKey = sizeof(int)*MALLOC_LOG_FRAMES;
|
||||
int aKey[MALLOC_LOG_KEYINTS];
|
||||
int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
|
||||
|
||||
memset(aKey, 0, nKey);
|
||||
if( (sizeof(void*)*nFrame)<nKey ){
|
||||
@@ -781,7 +784,7 @@ static void test_memdebug_log_clear(void){
|
||||
Tcl_Free((char *)pLog);
|
||||
}
|
||||
Tcl_DeleteHashTable(&aMallocLog);
|
||||
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES);
|
||||
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
|
||||
}
|
||||
|
||||
static int test_memdebug_log(
|
||||
@@ -804,7 +807,7 @@ static int test_memdebug_log(
|
||||
void (*xBacktrace)(int, int, void **));
|
||||
sqlite3MemdebugBacktraceCallback(test_memdebug_callback);
|
||||
#endif
|
||||
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES);
|
||||
Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
|
||||
isInit = 1;
|
||||
}
|
||||
|
||||
@@ -827,7 +830,7 @@ static int test_memdebug_log(
|
||||
Tcl_HashEntry *pEntry;
|
||||
Tcl_Obj *pRet = Tcl_NewObj();
|
||||
|
||||
assert(sizeof(int)==sizeof(void*));
|
||||
assert(sizeof(Tcl_WideInt)>=sizeof(void*));
|
||||
|
||||
for(
|
||||
pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
|
||||
@@ -836,13 +839,13 @@ static int test_memdebug_log(
|
||||
){
|
||||
Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2];
|
||||
MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
|
||||
int *aKey = (int *)Tcl_GetHashKey(&aMallocLog, pEntry);
|
||||
Tcl_WideInt *aKey = (Tcl_WideInt *)Tcl_GetHashKey(&aMallocLog, pEntry);
|
||||
int ii;
|
||||
|
||||
apElem[0] = Tcl_NewIntObj(pLog->nCall);
|
||||
apElem[1] = Tcl_NewIntObj(pLog->nByte);
|
||||
for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){
|
||||
apElem[ii+2] = Tcl_NewIntObj(aKey[ii]);
|
||||
apElem[ii+2] = Tcl_NewWideIntObj(aKey[ii]);
|
||||
}
|
||||
|
||||
Tcl_ListObjAppendElement(interp, pRet,
|
||||
|
||||
@@ -376,7 +376,13 @@ static int statNext(sqlite3_vtab_cursor *pCursor){
|
||||
if( pCsr->aPage[0].pPg==0 ){
|
||||
rc = sqlite3_step(pCsr->pStmt);
|
||||
if( rc==SQLITE_ROW ){
|
||||
int nPage;
|
||||
u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1);
|
||||
sqlite3PagerPagecount(pPager, &nPage);
|
||||
if( nPage==0 ){
|
||||
pCsr->isEof = 1;
|
||||
return sqlite3_reset(pCsr->pStmt);
|
||||
}
|
||||
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
|
||||
pCsr->aPage[0].iPgno = iRoot;
|
||||
pCsr->aPage[0].iCell = 0;
|
||||
@@ -486,17 +492,9 @@ static int statFilter(
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
sqlite3 *db = ((StatTable *)(pCursor->pVtab))->db;
|
||||
StatCursor *pCsr = (StatCursor *)pCursor;
|
||||
int nPage = 0;
|
||||
|
||||
statResetCsr((StatCursor *)pCursor);
|
||||
sqlite3PagerPagecount(sqlite3BtreePager(db->aDb[0].pBt), &nPage);
|
||||
if( nPage==0 ){
|
||||
pCsr->isEof = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
return statNext(pCursor);
|
||||
}
|
||||
|
||||
|
||||
27
src/wal.c
27
src/wal.c
@@ -1521,6 +1521,7 @@ static int walCheckpoint(
|
||||
u32 iDbpage = 0; /* Next database page to write */
|
||||
u32 iFrame = 0; /* Wal frame containing data for iDbpage */
|
||||
u32 mxSafeFrame; /* Max frame that can be backfilled */
|
||||
u32 mxPage; /* Max database page to write */
|
||||
int i; /* Loop counter */
|
||||
volatile WalCkptInfo *pInfo; /* The checkpoint status information */
|
||||
|
||||
@@ -1545,6 +1546,7 @@ static int walCheckpoint(
|
||||
** cannot be backfilled from the WAL.
|
||||
*/
|
||||
mxSafeFrame = pWal->hdr.mxFrame;
|
||||
mxPage = pWal->hdr.nPage;
|
||||
pInfo = walCkptInfo(pWal);
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
u32 y = pInfo->aReadMark[i];
|
||||
@@ -1565,6 +1567,7 @@ static int walCheckpoint(
|
||||
if( pInfo->nBackfill<mxSafeFrame
|
||||
&& (rc = walLockExclusive(pWal, WAL_READ_LOCK(0), 1))==SQLITE_OK
|
||||
){
|
||||
i64 nSize; /* Current size of database file */
|
||||
u32 nBackfill = pInfo->nBackfill;
|
||||
|
||||
/* Sync the WAL to disk */
|
||||
@@ -1572,11 +1575,22 @@ static int walCheckpoint(
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
|
||||
/* If the database file may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nReq = ((i64)mxPage * szPage);
|
||||
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
|
||||
if( rc==SQLITE_OK && nSize<nReq ){
|
||||
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate through the contents of the WAL, copying data to the db file. */
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue;
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
|
||||
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
|
||||
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
|
||||
@@ -2031,6 +2045,7 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
|
||||
** read-lock.
|
||||
*/
|
||||
void sqlite3WalEndReadTransaction(Wal *pWal){
|
||||
sqlite3WalEndWriteTransaction(pWal);
|
||||
if( pWal->readLock>=0 ){
|
||||
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
|
||||
pWal->readLock = -1;
|
||||
@@ -2153,11 +2168,13 @@ int sqlite3WalRead(
|
||||
|
||||
|
||||
/*
|
||||
** Set *pPgno to the size of the database file (or zero, if unknown).
|
||||
** Return the size of the database in pages (or zero, if unknown).
|
||||
*/
|
||||
void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno){
|
||||
assert( pWal->readLock>=0 || pWal->lockError );
|
||||
*pPgno = pWal->hdr.nPage;
|
||||
Pgno sqlite3WalDbsize(Wal *pWal){
|
||||
if( pWal && pWal->readLock>=0 ){
|
||||
return pWal->hdr.nPage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
# define sqlite3WalBeginReadTransaction(y,z) 0
|
||||
# define sqlite3WalEndReadTransaction(z)
|
||||
# define sqlite3WalRead(v,w,x,y,z) 0
|
||||
# define sqlite3WalDbsize(y,z)
|
||||
# define sqlite3WalDbsize(y) 0
|
||||
# define sqlite3WalBeginWriteTransaction(y) 0
|
||||
# define sqlite3WalEndWriteTransaction(x) 0
|
||||
# define sqlite3WalUndo(x,y,z) 0
|
||||
@@ -61,9 +61,8 @@ void sqlite3WalEndReadTransaction(Wal *pWal);
|
||||
/* Read a page from the write-ahead log, if it is present. */
|
||||
int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
|
||||
|
||||
/* Return the size of the database as it existed at the beginning
|
||||
** of the snapshot */
|
||||
void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno);
|
||||
/* If the WAL is not empty, return the size of the database. */
|
||||
Pgno sqlite3WalDbsize(Wal *pWal);
|
||||
|
||||
/* Obtain or release the WRITER lock. */
|
||||
int sqlite3WalBeginWriteTransaction(Wal *pWal);
|
||||
|
||||
@@ -403,7 +403,6 @@ do_test analyze3-3.6.5 {
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_test analyze3-3.7.1 {
|
||||
breakpoint
|
||||
set S [sqlite3_prepare_v2 db {
|
||||
SELECT * FROM t1 WHERE a IN (
|
||||
?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
|
||||
|
||||
@@ -55,6 +55,12 @@ proc lookaside {db} {
|
||||
#
|
||||
foreach ::lookaside_buffer_size {0 64 120} {
|
||||
|
||||
# Do not run any of these tests if there is SQL configured to run
|
||||
# as part of the [sqlite3] command. This prevents the script from
|
||||
# configuring the size of the lookaside buffer after [sqlite3] has
|
||||
# returned.
|
||||
if {[presql] != ""} break
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests for SQLITE_DBSTATUS_SCHEMA_USED.
|
||||
#
|
||||
@@ -317,6 +323,7 @@ foreach ::lookaside_buffer_size {0 64 120} {
|
||||
# implementation using sqlite3_mprintf() is technically considered
|
||||
# external and so is not counted as "statement memory".
|
||||
#
|
||||
puts "$nStmt1 $nFree"
|
||||
if {[string match *x $tn]} {
|
||||
do_test dbstatus-3.$tn.bx { expr $nStmt1<=$nFree } {1}
|
||||
} else {
|
||||
|
||||
@@ -253,6 +253,11 @@ db2 close
|
||||
# from being inspected externally.
|
||||
#
|
||||
if {$tcl_platform(platform) != "windows"} {
|
||||
|
||||
# Return a list of two booleans (either 0 or 1). The first is true
|
||||
# if the named file exists. The second is true only if the file
|
||||
# exists and the first 28 bytes contain at least one non-zero byte.
|
||||
#
|
||||
proc filestate {fname} {
|
||||
set exists 0
|
||||
set content 0
|
||||
@@ -263,6 +268,7 @@ if {$tcl_platform(platform) != "windows"} {
|
||||
}
|
||||
list $exists $content
|
||||
}
|
||||
|
||||
do_test exclusive-3.0 {
|
||||
filestate test.db-journal
|
||||
} {0 0}
|
||||
|
||||
146
test/fallocate.test
Normal file
146
test/fallocate.test
Normal file
@@ -0,0 +1,146 @@
|
||||
# 2010 July 28
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
file_control_chunksize_test db main [expr 1024*1024]
|
||||
|
||||
do_test fallocate-1.1 {
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA auto_vacuum = 1;
|
||||
CREATE TABLE t1(a, b);
|
||||
}
|
||||
file size test.db
|
||||
} [expr 1*1024*1024]
|
||||
|
||||
do_test fallocate-1.2 {
|
||||
execsql { INSERT INTO t1 VALUES(1, zeroblob(1024*900)) }
|
||||
file size test.db
|
||||
} [expr 1*1024*1024]
|
||||
|
||||
do_test fallocate-1.3 {
|
||||
execsql { INSERT INTO t1 VALUES(2, zeroblob(1024*900)) }
|
||||
file size test.db
|
||||
} [expr 2*1024*1024]
|
||||
|
||||
do_test fallocate-1.4 {
|
||||
execsql { DELETE FROM t1 WHERE a = 1 }
|
||||
file size test.db
|
||||
} [expr 1*1024*1024]
|
||||
|
||||
do_test fallocate-1.5 {
|
||||
execsql { DELETE FROM t1 WHERE a = 2 }
|
||||
file size test.db
|
||||
} [expr 1*1024*1024]
|
||||
|
||||
do_test fallocate-1.6 {
|
||||
execsql { PRAGMA freelist_count }
|
||||
} {0}
|
||||
|
||||
# Start a write-transaction and read the "database file size" field from
|
||||
# the journal file. This field should be set to the number of pages in
|
||||
# the database file based on the size of the file on disk, not the actual
|
||||
# logical size of the database within the file.
|
||||
#
|
||||
# We need to check this to verify that if in the unlikely event a rollback
|
||||
# causes a database file to grow, the database grows to its previous size
|
||||
# on disk, not to the minimum size required to hold the database image.
|
||||
#
|
||||
do_test fallocate-1.7 {
|
||||
execsql { BEGIN; INSERT INTO t1 VALUES(1, 2); }
|
||||
if {[permutation] != "inmemory_journal"} {
|
||||
hexio_get_int [hexio_read test.db-journal 16 4]
|
||||
} else {
|
||||
set {} 1024
|
||||
}
|
||||
} {1024}
|
||||
do_test fallocate-1.8 { execsql { COMMIT } } {}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests - fallocate-2.* - test that things work in WAL
|
||||
# mode as well.
|
||||
#
|
||||
set skipwaltests [expr {
|
||||
[permutation]=="journaltest" || [permutation]=="inmemory_journal"
|
||||
}]
|
||||
ifcapable !wal { set skipwaltests 1 }
|
||||
|
||||
if {!$skipwaltests} {
|
||||
db close
|
||||
file delete -force test.db
|
||||
sqlite3 db test.db
|
||||
file_control_chunksize_test db main [expr 32*1024]
|
||||
|
||||
do_test fallocate-2.1 {
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA journal_mode = WAL;
|
||||
CREATE TABLE t1(a, b);
|
||||
}
|
||||
file size test.db
|
||||
} [expr 32*1024]
|
||||
|
||||
do_test fallocate-2.2 {
|
||||
execsql { INSERT INTO t1 VALUES(1, zeroblob(35*1024)) }
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
file size test.db
|
||||
} [expr 64*1024]
|
||||
|
||||
do_test fallocate-2.3 {
|
||||
execsql { DELETE FROM t1 }
|
||||
execsql { VACUUM }
|
||||
file size test.db
|
||||
} [expr 64*1024]
|
||||
|
||||
do_test fallocate-2.4 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
file size test.db
|
||||
} [expr 32*1024]
|
||||
|
||||
do_test fallocate-2.5 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(2, randomblob(35*1024));
|
||||
PRAGMA wal_checkpoint;
|
||||
INSERT INTO t1 VALUES(3, randomblob(128));
|
||||
DELETE FROM t1 WHERE a = 2;
|
||||
VACUUM;
|
||||
}
|
||||
file size test.db
|
||||
} [expr 64*1024]
|
||||
|
||||
do_test fallocate-2.6 {
|
||||
sqlite3 db2 test.db
|
||||
execsql { BEGIN ; SELECT count(a) FROM t1 } db2
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(4, randomblob(128));
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
file size test.db
|
||||
} [expr 64*1024]
|
||||
|
||||
do_test fallocate-2.7 {
|
||||
execsql { SELECT count(b) FROM t1 } db2
|
||||
} {1}
|
||||
|
||||
do_test fallocate-2.8 {
|
||||
execsql { COMMIT } db2
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
file size test.db
|
||||
} [expr 32*1024]
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -524,4 +524,35 @@ ifcapable pragma {
|
||||
do_test jrnlmode-7.2 { file size test.db } {1024}
|
||||
}
|
||||
|
||||
do_execsql_test jrnlmode-8.1 { PRAGMA locking_mode=EXCLUSIVE } {exclusive}
|
||||
do_execsql_test jrnlmode-8.2 { CREATE TABLE t1(x) } {}
|
||||
do_execsql_test jrnlmode-8.3 { INSERT INTO t1 VALUES(123) } {}
|
||||
do_execsql_test jrnlmode-8.4 { SELECT * FROM t1 } {123}
|
||||
do_execsql_test jrnlmode-8.5 { PRAGMA journal_mode=PERSIST } {persist}
|
||||
do_execsql_test jrnlmode-8.6 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.7 { PRAGMA journal_mode=TRUNCATE } {truncate}
|
||||
do_execsql_test jrnlmode-8.8 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.9 { CREATE TABLE t2(y) } {}
|
||||
do_execsql_test jrnlmode-8.10 { INSERT INTO t2 VALUES(456) } {}
|
||||
do_execsql_test jrnlmode-8.11 { SELECT * FROM t1, t2 } {123 456}
|
||||
do_execsql_test jrnlmode-8.12 { PRAGMA locking_mode=NORMAL } {normal}
|
||||
do_execsql_test jrnlmode-8.13 { PRAGMA journal_mode=PERSIST } {persist}
|
||||
do_execsql_test jrnlmode-8.14 { PRAGMA journal_mode=TRUNCATE } {truncate}
|
||||
do_execsql_test jrnlmode-8.15 { PRAGMA journal_mode=PERSIST } {persist}
|
||||
do_execsql_test jrnlmode-8.16 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.17 { PRAGMA journal_mode=TRUNCATE } {truncate}
|
||||
do_execsql_test jrnlmode-8.18 { PRAGMA locking_mode=EXCLUSIVE } {exclusive}
|
||||
do_execsql_test jrnlmode-8.19 { CREATE TABLE t3(z) } {}
|
||||
do_execsql_test jrnlmode-8.20 { BEGIN IMMEDIATE } {}
|
||||
do_execsql_test jrnlmode-8.21 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.22 { COMMIT } {}
|
||||
do_execsql_test jrnlmode-8.23 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.24 { PRAGMA journal_mode=TRUNCATE } {truncate}
|
||||
do_execsql_test jrnlmode-8.25 { PRAGMA locking_mode=NORMAL } {normal}
|
||||
do_execsql_test jrnlmode-8.26 { CREATE TABLE t4(w) } {}
|
||||
do_execsql_test jrnlmode-8.27 { BEGIN IMMEDIATE } {}
|
||||
do_execsql_test jrnlmode-8.28 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.29 { COMMIT } {}
|
||||
do_execsql_test jrnlmode-8.30 { PRAGMA journal_mode=DELETE } {delete}
|
||||
|
||||
finish_test
|
||||
|
||||
33
test/pager3.test
Normal file
33
test/pager3.test
Normal file
@@ -0,0 +1,33 @@
|
||||
# 2010 June 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
|
||||
foreach {tn sql res j} {
|
||||
1 "PRAGMA journal_mode = DELETE" delete 0
|
||||
2 "CREATE TABLE t1(a, b)" {} 0
|
||||
3 "PRAGMA locking_mode=EXCLUSIVE" {exclusive} 0
|
||||
4 "INSERT INTO t1 VALUES(1, 2)" {} 1
|
||||
5 "PRAGMA locking_mode=NORMAL" {normal} 1
|
||||
6 "SELECT * FROM t1" {1 2} 0
|
||||
} {
|
||||
do_execsql_test pager3-1.$tn.1 $sql $res
|
||||
do_test pager3-1.$tn.2 { file exists test.db-journal } $j
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -517,6 +517,7 @@ static void opendb_x(
|
||||
pDb->db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize
|
||||
);
|
||||
sqlite3_busy_handler(pDb->db, busyhandler, 0);
|
||||
sqlite3_exec(pDb->db, "PRAGMA synchronous=OFF", 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1219,6 +1220,58 @@ static void walthread5(int nMs){
|
||||
print_and_free_err(&err);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
** Test case "cgt_pager_1"
|
||||
*/
|
||||
#define CALLGRINDTEST1_NROW 10000
|
||||
static void cgt_pager_1_populate(Error *pErr, Sqlite *pDb){
|
||||
const char *zInsert = "INSERT INTO t1 VALUES(:iRow, zeroblob(:iBlob))";
|
||||
i64 iRow;
|
||||
sql_script(pErr, pDb, "BEGIN");
|
||||
for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
|
||||
i64 iBlob = 600 + (iRow%300);
|
||||
execsql(pErr, pDb, zInsert, &iRow, &iBlob);
|
||||
}
|
||||
sql_script(pErr, pDb, "COMMIT");
|
||||
}
|
||||
static void cgt_pager_1_update(Error *pErr, Sqlite *pDb){
|
||||
const char *zUpdate = "UPDATE t1 SET b = zeroblob(:iBlob) WHERE a = :iRow";
|
||||
i64 iRow;
|
||||
sql_script(pErr, pDb, "BEGIN");
|
||||
for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
|
||||
i64 iBlob = 600 + ((iRow+100)%300);
|
||||
execsql(pErr, pDb, zUpdate, &iBlob, &iRow);
|
||||
}
|
||||
sql_script(pErr, pDb, "COMMIT");
|
||||
}
|
||||
static void cgt_pager_1_read(Error *pErr, Sqlite *pDb){
|
||||
i64 iRow;
|
||||
sql_script(pErr, pDb, "BEGIN");
|
||||
for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
|
||||
execsql(pErr, pDb, "SELECT * FROM t1 WHERE a = :iRow", &iRow);
|
||||
}
|
||||
sql_script(pErr, pDb, "COMMIT");
|
||||
}
|
||||
static void cgt_pager_1(int nMs){
|
||||
void (*xSub)(Error *, Sqlite *);
|
||||
Error err = {0};
|
||||
Sqlite db = {0};
|
||||
|
||||
opendb(&err, &db, "test.db", 1);
|
||||
sql_script(&err, &db,
|
||||
"PRAGMA cache_size = 2000;"
|
||||
"PRAGMA page_size = 1024;"
|
||||
"CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);"
|
||||
);
|
||||
|
||||
xSub = cgt_pager_1_populate; xSub(&err, &db);
|
||||
xSub = cgt_pager_1_update; xSub(&err, &db);
|
||||
xSub = cgt_pager_1_read; xSub(&err, &db);
|
||||
|
||||
closedb(&err, &db);
|
||||
print_and_free_err(&err);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
struct ThreadTest {
|
||||
void (*xTest)(int);
|
||||
@@ -1230,6 +1283,9 @@ int main(int argc, char **argv){
|
||||
{ walthread3, "walthread3", 20000 },
|
||||
{ walthread4, "walthread4", 20000 },
|
||||
{ walthread5, "walthread5", 1000 },
|
||||
{ walthread5, "walthread5", 1000 },
|
||||
|
||||
{ cgt_pager_1, "cgt_pager_1", 0 },
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
@@ -456,7 +456,7 @@ do_test wal2-6.1.5 {
|
||||
SELECT * FROM t1;
|
||||
PRAGMA lock_status;
|
||||
}
|
||||
} {1 2 main exclusive temp closed}
|
||||
} {1 2 main shared temp closed}
|
||||
do_test wal2-6.1.6 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
@@ -522,7 +522,7 @@ do_test wal2-6.2.8 {
|
||||
SELECT * FROM t1;
|
||||
pragma lock_status;
|
||||
}
|
||||
} {1 2 3 4 main exclusive temp closed}
|
||||
} {1 2 3 4 main shared temp closed}
|
||||
do_test wal2-6.2.9 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
@@ -608,6 +608,11 @@ set READMARK1_SET {
|
||||
set READMARK1_READ {
|
||||
{4 1 lock shared} {4 1 unlock shared}
|
||||
}
|
||||
set READMARK1_WRITE {
|
||||
{4 1 lock shared}
|
||||
{0 1 lock exclusive} {0 1 unlock exclusive}
|
||||
{4 1 unlock shared}
|
||||
}
|
||||
|
||||
foreach {tn sql res expected_locks} {
|
||||
2 {
|
||||
@@ -664,13 +669,9 @@ foreach {tn sql res expected_locks} {
|
||||
|
||||
9 {
|
||||
SELECT * FROM t1 ORDER BY x
|
||||
} {Arthur {Julius Henry} Karl Leonard} { }
|
||||
} {Arthur {Julius Henry} Karl Leonard} $READMARK1_READ
|
||||
|
||||
10 {
|
||||
DELETE FROM t1
|
||||
} {} {
|
||||
$READMARK1_READ
|
||||
}
|
||||
10 { DELETE FROM t1 } {} $READMARK1_WRITE
|
||||
|
||||
11 {
|
||||
SELECT * FROM t1
|
||||
@@ -942,7 +943,6 @@ do_test wal2-10.2.2 {
|
||||
set hdr [set_tvfs_hdr $::filename]
|
||||
lindex $hdr 0
|
||||
} {3007000}
|
||||
breakpoint
|
||||
do_test wal2-10.2.3 {
|
||||
lset hdr 0 3007001
|
||||
wal_fix_walindex_cksum hdr
|
||||
|
||||
@@ -110,6 +110,11 @@ for {set i 1} {$i < 50} {incr i} {
|
||||
db2 close
|
||||
}
|
||||
|
||||
proc byte_is_zero {file offset} {
|
||||
if {[file size test.db] <= $offset} { return 1 }
|
||||
expr { [hexio_read $file $offset 1] == "00" }
|
||||
}
|
||||
|
||||
do_multiclient_test i {
|
||||
|
||||
set testname(1) multiproc
|
||||
@@ -158,22 +163,24 @@ do_multiclient_test i {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
file size test.db
|
||||
} [expr $AUTOVACUUM ? 4*1024 : 3*1024]
|
||||
byte_is_zero test.db [expr $AUTOVACUUM ? 4*1024 : 3*1024]
|
||||
} {1}
|
||||
do_test wal3-2.$tn.5 {
|
||||
sql2 {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
file size test.db
|
||||
} [expr $AUTOVACUUM ? 5*1024 : 4*1024]
|
||||
list [byte_is_zero test.db [expr $AUTOVACUUM ? 4*1024 : 3*1024]] \
|
||||
[byte_is_zero test.db [expr $AUTOVACUUM ? 5*1024 : 4*1024]]
|
||||
} {0 1}
|
||||
do_test wal3-2.$tn.6 {
|
||||
sql3 {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
file size test.db
|
||||
} [expr $AUTOVACUUM ? 5*1024 : 4*1024]
|
||||
list [byte_is_zero test.db [expr $AUTOVACUUM ? 4*1024 : 3*1024]] \
|
||||
[byte_is_zero test.db [expr $AUTOVACUUM ? 5*1024 : 4*1024]]
|
||||
} {0 1}
|
||||
}
|
||||
catch {db close}
|
||||
|
||||
@@ -700,6 +707,7 @@ do_test wal3-9.0 {
|
||||
file delete -force test.db test.db-journal test.db wal
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA journal_mode = WAL;
|
||||
CREATE TABLE whoami(x);
|
||||
INSERT INTO whoami VALUES('nobody');
|
||||
@@ -722,15 +730,19 @@ for {set i 0} {$i < 50} {incr i} {
|
||||
execsql { SELECT * FROM whoami } $c
|
||||
} $c
|
||||
}
|
||||
|
||||
set sz [expr 1024 * (2+$AUTOVACUUM)]
|
||||
do_test wal3-9.3 {
|
||||
for {set i 0} {$i < 49} {incr i} { db$i close }
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
set sz1 [file size test.db]
|
||||
byte_is_zero test.db [expr $sz-1024]
|
||||
} {1}
|
||||
do_test wal3-9.4 {
|
||||
db49 close
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
set sz2 [file size test.db]
|
||||
expr {$sz2 > $sz1}
|
||||
} {1}
|
||||
byte_is_zero test.db [expr $sz-1024]
|
||||
} {0}
|
||||
|
||||
db close
|
||||
|
||||
|
||||
@@ -377,4 +377,11 @@ sqlite3 db2 test.db2
|
||||
do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 } {wal}
|
||||
db2 close
|
||||
|
||||
do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
|
||||
do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {delete}
|
||||
do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {delete}
|
||||
do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL } {wal}
|
||||
do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {wal}
|
||||
do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {wal}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user