diff --git a/doc/lemon.html b/doc/lemon.html index 6a4d6dbd2c..2c65555972 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -282,7 +282,7 @@ tokens) and it honors the same commenting conventions as C and C++.
A terminal symbol (token) is any string of alphanumeric and underscore characters that begins with an upper case letter. -A terminal can contain lower class letters after the first character, +A terminal can contain lowercase letters after the first character, but the usual convention is to make terminals all upper case. A nonterminal, on the other hand, is any string of alphanumeric and underscore characters than begins with a lower case letter. diff --git a/manifest b/manifest index a887475f95..66407107f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\ssegfaulting\son\san\sincremental\sblob\swrite\sif\sSQLITE_ENABLE_PREUPDATE_HOOK\nset\sbut\sno\spre-update\shooks\sare\sdefined. -D 2011-08-03T21:32:11.649 +C Merge\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch. +D 2011-08-03T21:46:58.295 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -26,7 +26,7 @@ F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F configure 93e7e695581fa7bef4949161453d9845c5592ad0 x F configure.ac 298a759c086e72c013da459c2aec02a104f4224f F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad -F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 +F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549 F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1 @@ -175,10 +175,10 @@ F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c fcc717427a80b2ed225373f07b642dc1aad7490b F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 -F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f +F src/os_common.h 65a897143b64667d23ed329a7984b9b405accb58 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c dcd6d5782dd30e918dc3d111cdcb1883bfb95345 -F src/os_win.c c5eadb2c0fc11347296a660f77b9844090265c0c +F src/os_unix.c 51caec436f811fa387a85cf7b05f13962c7fe0dc +F src/os_win.c 60af92b1b1cc7aee13f5e0b5f9dde2d7abb41354 F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -193,14 +193,14 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d219c4b68d603cc734b6f9b1e2780fee12a1fa0d F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd -F src/sqlite.h.in 4cd98228ea9cbb0359aaf725fdbebcd37c082c6a +F src/sqlite.h.in db27d510c1016b3dfbac947bccfe7b648d1fa478 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 113559f0c2202c4e648b5d647d7b2409604fb516 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e85bada4bf1796274a2cd7b3db9a663f8df31880 -F src/test1.c 693d9a63dfe2c68b167080c99cab82f267f5a38e +F src/test1.c e7ea726d26b9007bae7907d8b40280c70ec6c504 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -225,7 +225,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 7ca7be34e0e09ef0ed6619544552ed95732e41f6 -F src/test_multiplex.c 991a60733dbde8c529043d466c5c44d180762561 +F src/test_multiplex.c 731fb740a9fd4b11cb7b1990c62fc88d01c90dfd F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -250,7 +250,7 @@ F src/update.c 2d67e24d5a44d8b1c0839bf2ee0c391593e852bf F src/utf.c c53eb7404b3eb5c1cbb5655c6a7a0e0ce6bd50f0 F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e -F src/vdbe.c 00061273468d03c6c5c0f6144ed219c0004cf849 +F src/vdbe.c 303d8b3bc93a464739c03b2fff51d360dcf1a163 F src/vdbe.h 322af148cceef120bb1ec9cff7f122e76abf94da F src/vdbeInt.h 3de6588b36c833969aebab202e1766d586c37ec2 F src/vdbeapi.c ddd061183e2c3015f676e53ee85fcaf306617e8e @@ -259,10 +259,10 @@ F src/vdbeblob.c fde0374afb0c512614aed191ac2683f6772d2b8f F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 -F src/wal.c 0c70ad7b1cac6005fa5e2cbefd23ee05e391c290 +F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 106cd9ab3eb410dfa7d0598194c277664bb2e9a3 +F src/where.c 7d09f4c1512affb60cc1190a4b33d121d4ce039a F test/8_3_names.test b93687beebd17f6ebf812405a6833bae5d1f4199 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -628,7 +628,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16 -F test/permutations.test df39e810d98a966218ef1391afb4e25491af698f +F test/permutations.test f9ad1fcadd10a7fd4014de58e61178c3329a5c03 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea @@ -748,6 +748,7 @@ F test/tkt-b72787b1.test e6b62b2b2785c04d0d698d6a603507e384165049 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 F test/tkt-cbd054fa6b.test f14f97ea43662e6f70c9e63287081e8be5d9d589 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7 +F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 F test/tkt-d82e3f3721.test 731359dfdcdb36fea0559cd33fec39dd0ceae8e6 F test/tkt-f3e5abed55.test 19fb59268da6f20a69a181b9c14154132d1c65e3 F test/tkt-f777251dc7a.test 6f24c053bc5cdb7e1e19be9a72c8887cf41d5e87 @@ -887,6 +888,7 @@ F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796 F test/vtabC.test 1cf7896ab6859bfe3074244b2b0e12de5cbdd766 F test/vtabD.test 74167b1578e5886fe4c886d6bef2fd1406444c42 F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61 +F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d @@ -894,7 +896,7 @@ F test/wal.test 5617ad308bfdb8a8885220d8a261a6096a8d7e57 F test/wal2.test aa0fb2314b3235be4503c06873e41ebfc0757782 F test/wal3.test d512a5c8b4aa345722d11e8f1671db7eb15a0e39 F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30 -F test/wal5.test f06a0427e06db00347e32eb9fa99d6a5c0f2d088 +F test/wal5.test 08e145a352b1223930c7f0a1de82a8747a99c322 F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe @@ -907,6 +909,7 @@ F test/walfault.test 58fce626359c9376fe35101b5c0f2df8040aa839 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 22ddccd073c817ac9ead62b88ac446e8dedc7d2c F test/walnoshm.test a074428046408f4eb5c6a00e09df8cc97ff93317 +F test/walpersist.test 45fb0c94fb63908e2d66b1d99ce4645bfce0fa1e F test/walro.test 2d5d69e2e99da19ce6faab340330234fc4ca0720 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933 @@ -924,7 +927,7 @@ F test/where9.test 24f19ad14bb1b831564ced5273e681e495662848 F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 -F test/win32lock.test 0a16a7df4a51575bda27529ac992a5a94e4a38bd +F test/win32lock.test e12fe40524705cde9a4f5af4668e811807807b84 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b @@ -965,7 +968,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P d5f4c4c0bf0d488db11c6ab0d26ca3554a57d0ff -R dc4862fa4ca184e0298413704bde1899 +P 62c446340475b52b843c0345eda32ebe86fa9159 a2135ad13049c170b33315a949b1544e6a136183 +R 734a54c8f931fe24e65682db655c7b9e U drh -Z abe606476a76771b05a5d0a0f3902dc5 +Z 34a261d71dea5b8394b2283d95dc3275 diff --git a/manifest.uuid b/manifest.uuid index 492ab34ae1..81043c95b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62c446340475b52b843c0345eda32ebe86fa9159 \ No newline at end of file +c5709036087b6b4fb6391ab7e4b4b870aac87a31 \ No newline at end of file diff --git a/src/os_common.h b/src/os_common.h index eba856be8a..aa3e18a8c5 100644 --- a/src/os_common.h +++ b/src/os_common.h @@ -30,10 +30,13 @@ #endif #ifdef SQLITE_DEBUG -int sqlite3OSTrace = 0; -#define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X #else -#define OSTRACE(X) +# define OSTRACE(X) #endif /* diff --git a/src/os_unix.c b/src/os_unix.c index b2956c1647..9e7b458214 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -250,8 +250,9 @@ struct unixFile { /* ** Allowed values for the unixFile.ctrlFlags bitmask: */ -#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ -#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ /* ** Include code that is common to all os_*.c files @@ -3395,13 +3396,19 @@ static int proxyFileControl(sqlite3_file*,int,void*); ** SQLITE_FCNTL_SIZE_HINT operation is a no-op for Unix. */ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ - if( pFile->szChunk ){ + { /* preserve indentation of removed "if" */ i64 nSize; /* Required file size */ + i64 szChunk; /* Chunk size */ struct stat buf; /* Used to hold return values of fstat() */ if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; - nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; + szChunk = pFile->szChunk; + if( szChunk==0 ){ + nSize = nByte; + }else{ + nSize = ((nByte+szChunk-1) / szChunk) * szChunk; + } if( nSize>(i64)buf.st_size ){ #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE @@ -3444,21 +3451,33 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ + unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((unixFile*)id)->eFileLock; + *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } case SQLITE_LAST_ERRNO: { - *(int*)pArg = ((unixFile*)id)->lastErrno; + *(int*)pArg = pFile->lastErrno; return SQLITE_OK; } case SQLITE_FCNTL_CHUNK_SIZE: { - ((unixFile*)id)->szChunk = *(int *)pArg; + pFile->szChunk = *(int *)pArg; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { - return fcntlSizeHint((unixFile *)id, *(i64 *)pArg); + return fcntlSizeHint(pFile, *(i64 *)pArg); + } + case SQLITE_FCNTL_PERSIST_WAL: { + int bPersist = *(int*)pArg; + if( bPersist<0 ){ + *(int*)pArg = (pFile->ctrlFlags & UNIXFILE_PERSIST_WAL)!=0; + }else if( bPersist==0 ){ + pFile->ctrlFlags &= ~UNIXFILE_PERSIST_WAL; + }else{ + pFile->ctrlFlags |= UNIXFILE_PERSIST_WAL; + } + return SQLITE_OK; } #ifndef NDEBUG /* The pager calls this method to signal that it has done @@ -4783,7 +4802,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** ** Even if a subsequent open() call does succeed, the consequences of ** not searching for a resusable file descriptor are not dire. */ - if( 0==stat(zPath, &sStat) ){ + if( 0==osStat(zPath, &sStat) ){ unixInodeInfo *pInode; unixEnterMutex(); @@ -4859,7 +4878,7 @@ static int findCreateFileMode( memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; - if( 0==stat(zDb, &sStat) ){ + if( 0==osStat(zDb, &sStat) ){ *pMode = sStat.st_mode & 0777; }else{ rc = SQLITE_IOERR_FSTAT; @@ -5204,7 +5223,7 @@ static int unixAccess( *pResOut = (osAccess(zPath, amode)==0); if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ struct stat buf; - if( 0==stat(zPath, &buf) && buf.st_size==0 ){ + if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ *pResOut = 0; } } diff --git a/src/os_win.c b/src/os_win.c index 2d4f0adad2..0ca5db6b42 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -102,8 +102,9 @@ struct winFile { const sqlite3_io_methods *pMethod; /*** Must be first ***/ sqlite3_vfs *pVfs; /* The VFS used to open this file */ HANDLE h; /* Handle for accessing the file */ - unsigned char locktype; /* Type of lock currently held on this file */ + u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ + u8 bPersistWal; /* True to persist WAL files */ DWORD lastErrno; /* The Windows errno from the last I/O error */ DWORD sectorSize; /* Sector size of the device file is on */ winShm *pShm; /* Instance of shared memory on this file */ @@ -1335,17 +1336,18 @@ static int winUnlock(sqlite3_file *id, int locktype){ ** Control and query of the open file handle. */ static int winFileControl(sqlite3_file *id, int op, void *pArg){ + winFile *pFile = (winFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((winFile*)id)->locktype; + *(int*)pArg = pFile->locktype; return SQLITE_OK; } case SQLITE_LAST_ERRNO: { - *(int*)pArg = (int)((winFile*)id)->lastErrno; + *(int*)pArg = (int)pFile->lastErrno; return SQLITE_OK; } case SQLITE_FCNTL_CHUNK_SIZE: { - ((winFile*)id)->szChunk = *(int *)pArg; + pFile->szChunk = *(int *)pArg; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { @@ -1355,6 +1357,15 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ SimulateIOErrorBenign(0); return SQLITE_OK; } + case SQLITE_FCNTL_PERSIST_WAL: { + int bPersist = *(int*)pArg; + if( bPersist<0 ){ + *(int*)pArg = pFile->bPersistWal; + }else{ + pFile->bPersistWal = bPersist!=0; + } + return SQLITE_OK; + } case SQLITE_FCNTL_SYNC_OMITTED: { return SQLITE_OK; } @@ -2452,11 +2463,13 @@ static int winAccess( return SQLITE_NOMEM; } if( isNT() ){ + int cnt = 0; WIN32_FILE_ATTRIBUTE_DATA sAttrData; memset(&sAttrData, 0, sizeof(sAttrData)); - if( GetFileAttributesExW((WCHAR*)zConverted, + while( !(rc = GetFileAttributesExW((WCHAR*)zConverted, GetFileExInfoStandard, - &sAttrData) ){ + &sAttrData)) && retryIoerr(&cnt) ){} + if( rc ){ /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file ** as if it does not exist. */ @@ -2468,6 +2481,7 @@ static int winAccess( attr = sAttrData.dwFileAttributes; } }else{ + logIoerr(cnt); if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename); free(zConverted); @@ -2492,7 +2506,8 @@ static int winAccess( rc = attr!=INVALID_FILE_ATTRIBUTES; break; case SQLITE_ACCESS_READWRITE: - rc = (attr & FILE_ATTRIBUTE_READONLY)==0; + rc = attr!=INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)==0; break; default: assert(!"Invalid flags argument"); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7354627fd5..d7f03f635f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -752,6 +752,20 @@ struct sqlite3_io_methods { ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. +** +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write AHead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -763,6 +777,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_FILE_POINTER 7 #define SQLITE_FCNTL_SYNC_OMITTED 8 #define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 /* ** CAPI3REF: Mutex Handle diff --git a/src/test1.c b/src/test1.c index 3301ab7403..9a5a50103f 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5129,6 +5129,38 @@ static int file_control_win32_av_retry( return TCL_OK; } +/* +** tclcmd: file_control_persist_wal DB PERSIST-FLAG +** +** This TCL command runs the sqlite3_file_control interface with +** the SQLITE_FCNTL_PERSIST_WAL opcode. +*/ +static int file_control_persist_wal( + 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 */ +){ + sqlite3 *db; + int rc; + int bPersist; + char z[100]; + + if( objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR; + rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist); + sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist); + Tcl_AppendResult(interp, z, (char*)0); + return TCL_OK; +} + /* ** tclcmd: sqlite3_vfs_list @@ -5928,6 +5960,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_chunksize_test", file_control_chunksize_test, 0 }, { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, + { "file_control_persist_wal", file_control_persist_wal, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 732df82cd7..d316847945 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -414,8 +414,8 @@ static void multiplexSubClose( ){ sqlite3_file *pSubOpen = pGroup->aReal[iChunk].p; if( pSubOpen ){ - if( pOrigVfs ) pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); pSubOpen->pMethods->xClose(pSubOpen); + if( pOrigVfs ) pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); sqlite3_free(pGroup->aReal[iChunk].p); } sqlite3_free(pGroup->aReal[iChunk].z); diff --git a/src/vdbe.c b/src/vdbe.c index 9c0fb5c032..7b233dd7b2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1037,6 +1037,11 @@ case OP_Move: { zMalloc = pOut->zMalloc; pOut->zMalloc = 0; sqlite3VdbeMemMove(pOut, pIn1); +#ifdef SQLITE_DEBUG + if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){ + pOut->pScopyFrom += p1 - pOp->p2; + } +#endif pIn1->zMalloc = zMalloc; REGISTER_TRACE(p2++, pOut); pIn1++; diff --git a/src/wal.c b/src/wal.c index b9a03dff23..3bc42ffb17 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1804,13 +1804,15 @@ int sqlite3WalClose( */ rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE); if( rc==SQLITE_OK ){ + int bPersistWal = -1; if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } rc = sqlite3WalCheckpoint( pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 ); - if( rc==SQLITE_OK ){ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal); + if( rc==SQLITE_OK && bPersistWal!=1 ){ isDelete = 1; } } diff --git a/src/where.c b/src/where.c index d312232868..21fb7f45f4 100644 --- a/src/where.c +++ b/src/where.c @@ -2142,6 +2142,7 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator==WO_IN ); testcase( pTerm->eOperator==WO_ISNULL ); if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; nTerm++; } @@ -2192,6 +2193,7 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator==WO_IN ); testcase( pTerm->eOperator==WO_ISNULL ); if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; pIdxCons[j].iColumn = pTerm->u.leftColumn; pIdxCons[j].iTermOffset = i; pIdxCons[j].op = (u8)pTerm->eOperator; diff --git a/test/permutations.test b/test/permutations.test index ad6199ac17..dd39466d72 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -523,7 +523,7 @@ test_suite "inmemory_journal" -description { # the number of fsync() calls. pager.test exclusive.test jrnlmode.test sync.test misc1.test journal1.test conflict.test crash8.test tkt3457.test io.test - journal3.test + journal3.test 8_3_names.test pager1.test async4.test corrupt.test filefmt.test pager2.test corrupt5.test corruptA.test pageropt.test @@ -532,7 +532,7 @@ test_suite "inmemory_journal" -description { stmt.test # WAL mode is different. - wal* tkt-2d1a5c67d.test + wal* tkt-2d1a5c67d.test backcompat.test }] ifcapable mem3 { @@ -729,7 +729,7 @@ test_suite "journaltest" -description { unregister_jt_vfs } -files [test_set $::allquicktests -exclude { wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test - async4.test bigfile.test + async4.test bigfile.test backcompat.test }] if {[info commands register_demovfs] != ""} { @@ -872,4 +872,3 @@ if {[info script] == $argv0} { main $argv finish_test } - diff --git a/test/tkt-d635236375.test b/test/tkt-d635236375.test new file mode 100644 index 0000000000..3fc782265e --- /dev/null +++ b/test/tkt-d635236375.test @@ -0,0 +1,38 @@ +# 2011 August 3 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing that bug [d63523637517386191d634e] +# has been fixed. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set ::testprefix tkt-d635236375 + +do_test 1.0 { + execsql { + CREATE TABLE t1(id1 INTEGER PRIMARY KEY); + INSERT INTO t1 VALUES(9999); + CREATE TABLE t2(id2 INTEGER PRIMARY KEY); + INSERT INTO t2 VALUES(12345); + INSERT INTO t2 VALUES(54321); + SELECT DISTINCT id1 AS x, id1 AS y FROM t1, t2; + } +} {9999 9999} +do_test 1.1 { + execsql { + SELECT count(*) FROM t1, t2 GROUP BY id1, id1; + } +} {2} + + +finish_test diff --git a/test/vtabF.test b/test/vtabF.test new file mode 100644 index 0000000000..b9341ea597 --- /dev/null +++ b/test/vtabF.test @@ -0,0 +1,45 @@ +# 2011 Aug 1 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# This file checks to make sure IS NOT NULL constraints work on +# virtual tables. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !vtab||!schema_pragmas { finish_test ; return } + +# Register the echo module +register_echo_module [sqlite3_connection_pointer db] + +do_test vtabE-1.1 { + execsql { + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + INSERT INTO t1 VALUES(10,110); + INSERT INTO t1 VALUES(11,111); + INSERT INTO t1 SELECT a+2, b+2 FROM t1; + INSERT INTO t1 SELECT null, b+4 FROM t1; + INSERT INTO t1 SELECT null, b+8 FROM t1; + INSERT INTO t1 SELECT null, b+16 FROM t1; + ANALYZE; + CREATE VIRTUAL TABLE tv1 USING echo(t1); + SELECT b FROM t1 WHERE a IS NOT NULL; + } +} {110 111 112 113} +do_test vtabE-1.2 { + execsql {SELECT b FROM tv1 WHERE a IS NOT NULL} +} {110 111 112 113} + + +finish_test diff --git a/test/wal5.test b/test/wal5.test index 0c700dfc50..af4056ccd2 100644 --- a/test/wal5.test +++ b/test/wal5.test @@ -235,14 +235,7 @@ foreach {testprefix do_wal_checkpoint} { do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {} do_test 2.3.$tn.6 { file_page_counts } {1 7 1 7} do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 7 5} - if {$tcl_platform(platform) == "windows"} { - # on unix, the size_hint is a no-op if no chunk size is set. - # the windows implementation does not have a similar check, - # and because of this, the db file size has an extra page. - do_test 2.3.$tn.8 { file_page_counts } {2 7 2 7} - } { - do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7} - } + do_test 2.3.$tn.8 { file_page_counts } {2 7 2 7} } # Check that checkpoints block on the correct locks. And respond correctly @@ -350,4 +343,3 @@ foreach {testprefix do_wal_checkpoint} { finish_test - diff --git a/test/walpersist.test b/test/walpersist.test new file mode 100644 index 0000000000..3f8b0b8930 --- /dev/null +++ b/test/walpersist.test @@ -0,0 +1,68 @@ +# 2011 July 26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for using WAL with persistent WAL file mode. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +set ::testprefix walpersist + +do_test walpersist-1.0 { + db eval { + PRAGMA journal_mode=WAL; + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(randomblob(5000)); + } + file exists test.db-wal +} {1} +do_test walpersist-1.1 { + file exists test.db-shm +} {1} +do_test walpersist-1.2 { + db close + list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] +} {1 0 0} +do_test walpersist-1.3 { + sqlite3 db test.db + db eval {SELECT length(a) FROM t1} +} {5000} +do_test walpersist-1.4 { + list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] +} {1 1 1} +do_test walpersist-1.5 { + file_control_persist_wal db -1 +} {0 0} +do_test walpersist-1.6 { + file_control_persist_wal db 1 +} {0 1} +do_test walpersist-1.7 { + file_control_persist_wal db -1 +} {0 1} +do_test walpersist-1.8 { + file_control_persist_wal db 0 +} {0 0} +do_test walpersist-1.9 { + file_control_persist_wal db -1 +} {0 0} +do_test walpersist-1.10 { + file_control_persist_wal db 1 +} {0 1} +do_test walpersist-1.11 { + db close + list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] +} {1 1 1} + + + + +finish_test diff --git a/test/win32lock.test b/test/win32lock.test index 802ea27d16..8ed467cfc8 100644 --- a/test/win32lock.test +++ b/test/win32lock.test @@ -57,7 +57,7 @@ while {1} { do_test win32lock-1.2-$delay1 { set ::msg } {1 100000 2 50000 3 25000 4 12500} - if {$::log!=""} { + if {[info exists ::log] && $::log!=""} { do_test win32lock-1.2-$delay1-log1 { regsub {\d+} $::log # x set x