1
0
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:
dan
2010-08-11 06:04:19 +00:00
23 changed files with 1948 additions and 1031 deletions

View File

@@ -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

View File

@@ -1 +1 @@
e82e32bd431ccacd276df8241592eb5519d87122
aa092ac928dc19bd356d25a1dfd3f432dc145ce6

View File

@@ -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

View File

@@ -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;
}
/*
@@ -718,42 +743,37 @@ static int winWrite(
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;
}
}
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 ){
if( nRem>0 ){
pFile->lastErrno = GetLastError();
rc = 1;
}
}
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);

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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 */

View File

@@ -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.
*/

View File

@@ -729,6 +729,9 @@ static int test_memdebug_settitle(
}
#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,

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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
View 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

View File

@@ -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
View 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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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