From 0e9365ced3105db6ec0909026d39bd7fc3db64f3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Mar 2011 02:08:13 +0000 Subject: [PATCH 01/35] Log all error from close() in os_unix.c to sqlite3_log() but do not attempt to report errors back up to the application. Update the unix error logging to put the most important information earlier in the message. FossilOrigin-Name: 7b6e30e6a712311d4ef275253b085b85e6e17116 --- manifest | 20 +++---- manifest.uuid | 2 +- src/os_unix.c | 141 ++++++++++++++++++++-------------------------- test/oserror.test | 11 ++-- 4 files changed, 77 insertions(+), 97 deletions(-) diff --git a/manifest b/manifest index 1d2716b2db..30c4b431b1 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Comment\sout\ssome\scode\sin\sos_unix.c\sthat\sonly\sruns\son\sMacOSX\swith\nSQLITE_ENABLE_LOCKING_STYLE. -D 2011-02-25T03:25:07.454 +C Log\sall\serror\sfrom\sclose()\sin\sos_unix.c\sto\ssqlite3_log()\sbut\sdo\snot\sattempt\sto\nreport\serrors\sback\sup\sto\sthe\sapplication.\s\sUpdate\sthe\sunix\serror\slogging\sto\nput\sthe\smost\simportant\sinformation\searlier\sin\sthe\smessage. +D 2011-03-02T02:08:13.207 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,7 +164,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 -F src/os_unix.c 64a2e0ebbb19765f97993b3920f795e6f38fd923 +F src/os_unix.c 5e2e1187c19cc20798dd9a08bee841fab0929ccf F src/os_win.c 9abdcdd925416d854eabb0996c96debd92abfef5 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -585,7 +585,7 @@ F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec -F test/oserror.test 5775264a41039856d211168713d916949227fedd +F test/oserror.test 8fc832600afe2b983f2347bfb3cbb88a80aeb347 F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f @@ -912,14 +912,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P af4756184a255f5d8a5cd276bf9f2fc3b38d9169 -R 86eab7753acb1a027109135cae01654a +P 4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a +R a9b7ad5c14ea738e4f49c429699cb565 U drh -Z 475e4dbe6e8fc13f5f8796d1c18d588c +Z c02292224bfb7c5f15d6a63d1b16838a -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNZyEhoxKgR168RlERAohiAKCDC55xIULyuJJBl/uNZNCMqVF+ZgCeK05+ -18x49YRlHX+qQrvL/cMA0OY= -=QUmN +iD8DBQFNbaaQoxKgR168RlERAshdAJ4iJDt6I1+oeLfL9JDapg61g0RrTgCfcFyC +s4eiT7ukCDxc6MYErF6v4VI= +=AyES -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index a2c2d650a2..0b4dc2a39e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a \ No newline at end of file +7b6e30e6a712311d4ef275253b085b85e6e17116 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 473432be5f..b70e2736bd 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -767,14 +767,15 @@ static unixInodeInfo *inodeList = 0; ** failed (e.g. "unlink", "open") and the the associated file-system path, ** if any. */ -#define unixLogError(a,b,c) unixLogError_x(a,b,c,__LINE__) -static int unixLogError_x( +#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) +static int unixLogErrorAtLine( int errcode, /* SQLite error code */ const char *zFunc, /* Name of OS function that failed */ const char *zPath, /* File path associated with error */ int iLine /* Source line number where error occurred */ ){ char *zErr; /* Message from strerror() or equivalent */ + int iErrno = errno; /* Saved syscall error number */ /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use ** the strerror() function to obtain the human-readable error message @@ -800,54 +801,59 @@ static int unixLogError_x( #if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) zErr = # endif - strerror_r(errno, aErr, sizeof(aErr)-1); + strerror_r(iErrno, aErr, sizeof(aErr)-1); #elif SQLITE_THREADSAFE /* This is a threadsafe build, but strerror_r() is not available. */ zErr = ""; #else /* Non-threadsafe build, use strerror(). */ - zErr = strerror(errno); + zErr = strerror(iErrno); #endif assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; sqlite3_log(errcode, - "os_unix.c: %s() at line %d - \"%s\" errno=%d path=%s", - zFunc, iLine, zErr, errno, (zPath ? zPath : "n/a") + "os_unix.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zErr ); return errcode; } +/* +** Close a file descriptor. +** +** We assume that close() almost always works, since it is only in a +** very sick application or on a very sick platform that it might fail. +** If it does fail, simply leak the file descriptor, but do log the +** error. +** +** Note that it is not safe to retry close() after EINTR since the +** file descriptor might have already been reused by another thread. +** So we don't even try to recover from an EINTR. Just log the error +** and move on. +*/ +static void robust_close(unixFile *pFile, int h, int lineno){ + if( close(h) ){ + unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", + pFile ? pFile->zPath : 0, lineno); + } +} /* ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. -** If all such file descriptors are closed without error, the list is -** cleared and SQLITE_OK returned. -** -** Otherwise, if an error occurs, then successfully closed file descriptor -** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. -** not deleted and SQLITE_IOERR_CLOSE returned. */ -static int closePendingFds(unixFile *pFile){ - int rc = SQLITE_OK; +static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; - UnixUnusedFd *pError = 0; UnixUnusedFd *p; UnixUnusedFd *pNext; for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; - if( close(p->fd) ){ - pFile->lastErrno = errno; - rc = unixLogError(SQLITE_IOERR_CLOSE, "close", pFile->zPath); - p->pNext = pError; - pError = p; - }else{ - sqlite3_free(p); - } + robust_close(pFile, p->fd, __LINE__); + sqlite3_free(p); } - pInode->pUnused = pError; - return rc; + pInode->pUnused = 0; } /* @@ -1458,10 +1464,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ pInode->nLock--; assert( pInode->nLock>=0 ); if( pInode->nLock==0 ){ - int rc2 = closePendingFds(pFile); - if( rc==SQLITE_OK ){ - rc = rc2; - } + closePendingFds(pFile); } } @@ -1496,20 +1499,12 @@ static int closeUnixFile(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; if( pFile ){ if( pFile->dirfd>=0 ){ - int err = close(pFile->dirfd); - if( err ){ - pFile->lastErrno = errno; - return unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", pFile->zPath); - }else{ - pFile->dirfd=-1; - } + robust_close(pFile, pFile->dirfd, __LINE__); + pFile->dirfd=-1; } if( pFile->h>=0 ){ - int err = close(pFile->h); - if( err ){ - pFile->lastErrno = errno; - return unixLogError(SQLITE_IOERR_CLOSE, "close", pFile->zPath); - } + robust_close(pFile, pFile->h, __LINE__); + pFile->h = -1; } #if OS_VXWORKS if( pFile->pId ){ @@ -1719,10 +1714,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } return rc; } - if( close(fd) ){ - pFile->lastErrno = errno; - rc = SQLITE_IOERR_CLOSE; - } + robust_close(pFile, fd, __LINE__); /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; @@ -2614,7 +2606,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { pInode->nLock--; assert( pInode->nLock>=0 ); if( pInode->nLock==0 ){ - rc = closePendingFds(pFile); + closePendingFds(pFile); } } } @@ -3047,7 +3039,6 @@ static int unixSync(sqlite3_file *id, int flags){ return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); } if( pFile->dirfd>=0 ){ - int err; OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd, HAVE_FULLFSYNC, isFullsync)); #ifndef SQLITE_DISABLE_DIRSYNC @@ -3066,13 +3057,9 @@ static int unixSync(sqlite3_file *id, int flags){ /* return SQLITE_IOERR; */ } #endif - err = close(pFile->dirfd); /* Only need to sync once, so close the */ - if( err==0 ){ /* directory when we are done */ - pFile->dirfd = -1; - }else{ - pFile->lastErrno = errno; - rc = unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", pFile->zPath); - } + /* Only need to sync once, so close the directory when we are done */ + robust_close(pFile, pFile->dirfd, __LINE__); + pFile->dirfd = -1; } return rc; } @@ -3439,7 +3426,10 @@ static void unixShmPurge(unixFile *pFd){ munmap(p->apRegion[i], p->szRegion); } sqlite3_free(p->apRegion); - if( p->h>=0 ) close(p->h); + if( p->h>=0 ){ + robust_close(pFd, p->h, __LINE__); + p->h = -1; + } p->pInode->pShmNode = 0; sqlite3_free(p); } @@ -4250,7 +4240,7 @@ static int fillInUnixFile( ** implicit assumption here is that if fstat() fails, things are in ** such bad shape that dropping a lock or two doesn't matter much. */ - close(h); + robust_close(pNew, h, __LINE__); h = -1; } unixLeaveMutex(); @@ -4276,7 +4266,7 @@ static int fillInUnixFile( rc = findInodeInfo(pNew, &pNew->pInode); if( rc!=SQLITE_OK ){ sqlite3_free(pNew->lockingContext); - close(h); + robust_close(pNew, h, __LINE__); h = -1; } unixLeaveMutex(); @@ -4327,7 +4317,7 @@ static int fillInUnixFile( pNew->lastErrno = 0; #if OS_VXWORKS if( rc!=SQLITE_OK ){ - if( h>=0 ) close(h); + if( h>=0 ) robust_close(pNew, h, __LINE__); h = -1; unlink(zFilename); isDelete = 0; @@ -4335,8 +4325,8 @@ static int fillInUnixFile( pNew->isDelete = isDelete; #endif if( rc!=SQLITE_OK ){ - if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */ - if( h>=0 ) close(h); + if( dirfd>=0 ) robust_close(pNew, dirfd, __LINE__); + if( h>=0 ) robust_close(pNew, h, __LINE__); }else{ pNew->pMethod = pLockingStyle; OpenCounter(+1); @@ -4748,7 +4738,7 @@ static int unixOpen( ** it would not be safe to close as this would release any locks held ** on the file by this process. */ assert( eType!=SQLITE_OPEN_MAIN_DB ); - close(fd); /* silently leak if fail, already in error */ + robust_close(p, fd, __LINE__); goto open_finished; } } @@ -4764,8 +4754,8 @@ static int unixOpen( struct statfs fsInfo; if( fstatfs(fd, &fsInfo) == -1 ){ ((unixFile*)pFile)->lastErrno = errno; - if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */ - close(fd); /* silently leak if fail, in error */ + if( dirfd>=0 ) robust_close(p, dirfd, __LINE__); + robust_close(p, fd, __LINE__); return SQLITE_IOERR_ACCESS; } if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { @@ -4797,9 +4787,9 @@ static int unixOpen( ** the same file are working. */ p->lastErrno = errno; if( dirfd>=0 ){ - close(dirfd); /* silently leak if fail, in error */ + robust_close(p, dirfd, __LINE__); } - close(fd); /* silently leak if fail, in error */ + robust_close(p, fd, __LINE__); rc = SQLITE_IOERR_ACCESS; goto open_finished; } @@ -4860,9 +4850,7 @@ static int unixDelete( { rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } - if( close(fd)&&!rc ){ - rc = unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", zPath); - } + robust_close(0, fd, __LINE__); } } #endif @@ -5050,7 +5038,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ nBuf = sizeof(t) + sizeof(pid); }else{ do{ nBuf = read(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); - close(fd); + robust_close(0, fd, __LINE__); } } #endif @@ -5493,7 +5481,7 @@ static int proxyCreateUnixFile( return SQLITE_OK; } end_create_proxy: - close(fd); /* silently leak fd if error, we're already in error */ + robust_close(pNew, fd, __LINE__); sqlite3_free(pNew); sqlite3_free(pUnused); return rc; @@ -5593,7 +5581,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ } rc = 0; fprintf(stderr, "broke stale lock on %s\n", cPath); - close(conchFile->h); + robust_close(pFile, conchFile->h, __LINE__); conchFile->h = fd; conchFile->openFlags = O_RDWR | O_CREAT; @@ -5601,7 +5589,7 @@ end_breaklock: if( rc ){ if( fd>=0 ){ unlink(tPath); - close(fd); + robust_close(pFile, fd, __LINE__); } fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); } @@ -5851,14 +5839,7 @@ static int proxyTakeConch(unixFile *pFile){ OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); if( rc==SQLITE_OK && pFile->openFlags ){ if( pFile->h>=0 ){ -#ifdef STRICT_CLOSE_ERROR - if( close(pFile->h) ){ - pFile->lastErrno = errno; - return SQLITE_IOERR_CLOSE; - } -#else - close(pFile->h); /* silently leak fd if fail */ -#endif + robust_close(pFile, pFile->h, __LINE__) ){ } pFile->h = -1; int fd = open(pCtx->dbPath, pFile->openFlags, diff --git a/test/oserror.test b/test/oserror.test index f2aa61008f..e44a674192 100644 --- a/test/oserror.test +++ b/test/oserror.test @@ -56,7 +56,7 @@ do_test 1.1.2 { catch { for {set i 0} {$i < 2000} {incr i} { dbh_$i close } } } {1} -do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c: open.*test.db$} +do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c:\d*: \(24\) open\(.*test.db\) - } # Test a failure in open() due to the path being a directory. @@ -67,7 +67,7 @@ do_test 1.2.1 { list [catch { sqlite3 dbh dir.db } msg] $msg } {1 {unable to open database file}} -do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c: open.*dir.db$} +do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c:\d*: \(21\) open\(.*dir.db\) - } # Test a failure in open() due to the path not existing. # @@ -76,7 +76,7 @@ do_test 1.3.1 { list [catch { sqlite3 dbh /x/y/z/test.db } msg] $msg } {1 {unable to open database file}} -do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c: open.*test.db$} +do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c:\d*: \(2\) open\(.*test.db\) - } # Test a failure in open() due to the path not existing. # @@ -85,7 +85,7 @@ do_test 1.4.1 { list [catch { sqlite3 dbh /root/test.db } msg] $msg } {1 {unable to open database file}} -do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c: open.*test.db$} +do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(13\) open\(.*test.db\) - } #-------------------------------------------------------------------------- # Tests oserror-1.* test failures in the unlink() system call. @@ -98,7 +98,7 @@ do_test 2.1.1 { catchsql { SELECT * FROM sqlite_master } dbh } {1 {disk I/O error}} -do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c: unlink.*test.db-wal$} +do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c:\d*: \(21\) unlink\(.*test.db-wal\) - } do_test 2.1.3 { dbh close forcedelete test.db-wal @@ -109,4 +109,3 @@ sqlite3_shutdown test_sqlite3_log sqlite3_initialize finish_test - From 99ab3b120e9667221338a6f0b3c844ec525bc5ed Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Mar 2011 15:09:07 +0000 Subject: [PATCH 02/35] Proof-of-concept prototype for the proposed xSetSystemCall extension method on the VFS. FossilOrigin-Name: 92b5a76abc53290e1bb87b6b55bc64bb1b331dfc --- manifest | 26 ++++--- manifest.uuid | 2 +- src/os_unix.c | 201 +++++++++++++++++++++++++++++++++--------------- src/os_win.c | 3 +- src/sqlite.h.in | 7 +- 5 files changed, 164 insertions(+), 75 deletions(-) diff --git a/manifest b/manifest index 30c4b431b1..db71d0c060 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Log\sall\serror\sfrom\sclose()\sin\sos_unix.c\sto\ssqlite3_log()\sbut\sdo\snot\sattempt\sto\nreport\serrors\sback\sup\sto\sthe\sapplication.\s\sUpdate\sthe\sunix\serror\slogging\sto\nput\sthe\smost\simportant\sinformation\searlier\sin\sthe\smessage. -D 2011-03-02T02:08:13.207 +C Proof-of-concept\sprototype\sfor\sthe\sproposed\sxSetSystemCall\sextension\smethod\non\sthe\sVFS. +D 2011-03-02T15:09:07.461 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,8 +164,8 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 -F src/os_unix.c 5e2e1187c19cc20798dd9a08bee841fab0929ccf -F src/os_win.c 9abdcdd925416d854eabb0996c96debd92abfef5 +F src/os_unix.c 34f0341ab45ba2708714c8e3f7bd35c7ccb5e34d +F src/os_win.c c2df806a8510ec8c2c2c30fb78b3a25bc1b2f325 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -180,7 +180,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d +F src/sqlite.h.in a2115e725e77ea1284a4df51b39f94121f020ab8 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 4290fff17fabc6e07fc4338233df0e39e6350ca1 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 @@ -912,14 +912,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a -R a9b7ad5c14ea738e4f49c429699cb565 +P 7b6e30e6a712311d4ef275253b085b85e6e17116 +R b432d469c6ed4dca97f566fa093fcbff +T *bgcolor * #a8d3c0 +T *branch * syscall-override +T *sym-syscall-override * +T -sym-trunk * U drh -Z c02292224bfb7c5f15d6a63d1b16838a +Z 9b09403dc20dd3b2e37d470a4feaa93c -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNbaaQoxKgR168RlERAshdAJ4iJDt6I1+oeLfL9JDapg61g0RrTgCfcFyC -s4eiT7ukCDxc6MYErF6v4VI= -=AyES +iD8DBQFNbl2aoxKgR168RlERAnuDAJ9BNtRHzGqMMOlHR9sjdCvks/uYWQCgiUgt +CkJFrHO5mCcgtbaMpvVY+k0= +=K2zl -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 0b4dc2a39e..ee6de5d921 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b6e30e6a712311d4ef275253b085b85e6e17116 \ No newline at end of file +92b5a76abc53290e1bb87b6b55bc64bb1b331dfc \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index b70e2736bd..d2263addc6 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -270,16 +270,6 @@ struct unixFile { # define O_BINARY 0 #endif -/* -** The DJGPP compiler environment looks mostly like Unix, but it -** lacks the fcntl() system call. So redefine fcntl() to be something -** that always succeeds. This means that locking does not occur under -** DJGPP. But it is DOS - what did you expect? -*/ -#ifdef __DJGPP__ -# define fcntl(A,B,C) 0 -#endif - /* ** The threadid macro resolves to the thread-id or to 0. Used for ** testing and debugging only. @@ -290,6 +280,93 @@ struct unixFile { #define threadid 0 #endif +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct unix_syscall { + const char *zName; /* Name of the sytem call */ + void *pCurrent; /* Current value of the system call */ + void *pDefault; /* Default value */ +} aSyscall[] = { + { "open", (void*)open, 0 }, +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) + + { "close", (void*)close, 0 }, +#define osClose ((int(*)(int))aSyscall[1].pCurrent) + + { "access", (void*)access, 0 }, +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) + + { "getcwd", (void*)getcwd, 0 }, +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) + + { "stat", (void*)stat, 0 }, +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) + +/* +** The DJGPP compiler environment looks mostly like Unix, but it +** lacks the fcntl() system call. So redefine fcntl() to be something +** that always succeeds. This means that locking does not occur under +** DJGPP. But it is DOS - what did you expect? +*/ +#ifdef __DJGPP__ + { "fstat", 0, 0 }, +#define osFstat(a,b,c) 0 +#else + { "fstat", (void*)fstat, 0 }, +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) +#endif + + { "ftruncate", (void*)ftruncate, 0 }, +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) + + { "fcntl", (void*)fcntl, 0 }, +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) +}; + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "unix" VFSes. +*/ +static int unixSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + void *pNewFunc /* Pointer to new system call value */ +){ + int i; + int rc = 0; + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + for(i=0; il_whence==SEEK_SET ); - s = fcntl(fd, op, p); + s = osFcntl(fd, op, p); savedErrno = errno; sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, @@ -376,7 +453,7 @@ static int lockTrace(int fd, int op, struct flock *p){ if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ struct flock l2; l2 = *p; - fcntl(fd, F_GETLK, &l2); + osFcntl(fd, F_GETLK, &l2); if( l2.l_type==F_RDLCK ){ zType = "RDLCK"; }else if( l2.l_type==F_WRLCK ){ @@ -392,7 +469,8 @@ static int lockTrace(int fd, int op, struct flock *p){ errno = savedErrno; return s; } -#define fcntl lockTrace +#undef osFcntl +#define osFcntl lockTrace #endif /* SQLITE_LOCK_TRACE */ @@ -402,11 +480,11 @@ static int lockTrace(int fd, int op, struct flock *p){ #ifdef EINTR static int robust_ftruncate(int h, sqlite3_int64 sz){ int rc; - do{ rc = ftruncate(h,sz); }while( rc<0 && errno==EINTR ); + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); return rc; } #else -# define robust_ftruncate(a,b) ftruncate(a,b) +# define robust_ftruncate(a,b) osFtruncate(a,b) #endif @@ -835,7 +913,7 @@ static int unixLogErrorAtLine( ** and move on. */ static void robust_close(unixFile *pFile, int h, int lineno){ - if( close(h) ){ + if( osClose(h) ){ unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", pFile ? pFile->zPath : 0, lineno); } @@ -912,7 +990,7 @@ static int findInodeInfo( ** create a unique name for the file. */ fd = pFile->h; - rc = fstat(fd, &statbuf); + rc = osFstat(fd, &statbuf); if( rc!=0 ){ pFile->lastErrno = errno; #ifdef EOVERFLOW @@ -938,7 +1016,7 @@ static int findInodeInfo( pFile->lastErrno = errno; return SQLITE_IOERR; } - rc = fstat(fd, &statbuf); + rc = osFstat(fd, &statbuf); if( rc!=0 ){ pFile->lastErrno = errno; return SQLITE_IOERR; @@ -1007,7 +1085,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; - if (-1 == fcntl(pFile->h, F_GETLK, &lock)) { + if (-1 == osFcntl(pFile->h, F_GETLK, &lock)) { int tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); pFile->lastErrno = tErrno; @@ -1160,7 +1238,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ){ lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); lock.l_start = PENDING_BYTE; - s = fcntl(pFile->h, F_SETLK, &lock); + s = osFcntl(pFile->h, F_SETLK, &lock); if( s==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); @@ -1182,14 +1260,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){ /* Now get the read-lock */ lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){ + if( (s = osFcntl(pFile->h, F_SETLK, &lock))==(-1) ){ tErrno = errno; } /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; - if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ + if( osFcntl(pFile->h, F_SETLK, &lock)!=0 ){ if( s != -1 ){ /* This could happen with a network mount */ tErrno = errno; @@ -1232,7 +1310,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ default: assert(0); } - s = fcntl(pFile->h, F_SETLK, &lock); + s = osFcntl(pFile->h, F_SETLK, &lock); if( s==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); @@ -1367,7 +1445,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( osFcntl(h, F_SETLK, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1379,7 +1457,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( osFcntl(h, F_SETLK, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1391,7 +1469,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST+divSize; lock.l_len = SHARED_SIZE-divSize; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( osFcntl(h, F_SETLK, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1406,7 +1484,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ + if( osFcntl(h, F_SETLK, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1420,7 +1498,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - if( fcntl(h, F_SETLK, &lock)!=(-1) ){ + if( osFcntl(h, F_SETLK, &lock)!=(-1) ){ pInode->eFileLock = SHARED_LOCK; }else{ tErrno = errno; @@ -1444,7 +1522,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); - if( fcntl(h, F_SETLK, &lock)!=(-1) ){ + if( osFcntl(h, F_SETLK, &lock)!=(-1) ){ pInode->eFileLock = NO_LOCK; }else{ tErrno = errno; @@ -1646,7 +1724,7 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { }else{ /* The lock is held if and only if the lockfile exists */ const char *zLockFile = (const char*)pFile->lockingContext; - reserved = access(zLockFile, 0)==0; + reserved = osAccess(zLockFile, 0)==0; } OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); *pResOut = reserved; @@ -1700,7 +1778,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } /* grab an exclusive lock */ - fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); + fd = osOpen(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); if( fd<0 ){ /* failed to open/create the file, someone else may have stolen the lock */ int tErrno = errno; @@ -2964,7 +3042,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ rc = SQLITE_OK; #elif HAVE_FULLFSYNC if( fullSync ){ - rc = fcntl(fd, F_FULLFSYNC, 0); + rc = osFcntl(fd, F_FULLFSYNC, 0); }else{ rc = 1; } @@ -3111,7 +3189,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ int rc; struct stat buf; assert( id ); - rc = fstat(((unixFile*)id)->h, &buf); + rc = osFstat(((unixFile*)id)->h, &buf); SimulateIOError( rc=1 ); if( rc!=0 ){ ((unixFile*)id)->lastErrno = errno; @@ -3152,7 +3230,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ i64 nSize; /* Required file size */ struct stat buf; /* Used to hold return values of fstat() */ - if( fstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; + if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; if( nSize>(i64)buf.st_size ){ @@ -3367,7 +3445,7 @@ static int unixShmSystemLock( f.l_start = ofst; f.l_len = n; - rc = fcntl(pShmNode->h, F_SETLK, &f); + rc = osFcntl(pShmNode->h, F_SETLK, &f); rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; /* Update the global lock state and do debug tracing */ @@ -3492,7 +3570,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** with the same permissions. The actual permissions the file is created ** with are subject to the current umask setting. */ - if( fstat(pDbFd->h, &sStat) ){ + if( osFstat(pDbFd->h, &sStat) ){ rc = SQLITE_IOERR_FSTAT; goto shm_open_err; } @@ -3525,7 +3603,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ goto shm_open_err; } - pShmNode->h = open(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777)); + pShmNode->h = osOpen(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); goto shm_open_err; @@ -3629,7 +3707,7 @@ static int unixShmMap( ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ - if( fstat(pShmNode->h, &sStat) ){ + if( osFstat(pShmNode->h, &sStat) ){ rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; } @@ -4088,7 +4166,7 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ return &nfsIoMethods; } else { @@ -4130,7 +4208,7 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { return &posixIoMethods; }else{ return &semIoMethods; @@ -4353,10 +4431,10 @@ static int openDirectory(const char *zFilename, int *pFd){ for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; - fd = open(zDirname, O_RDONLY|O_BINARY, 0); + fd = osOpen(zDirname, O_RDONLY|O_BINARY, 0); if( fd>=0 ){ #ifdef FD_CLOEXEC - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); #endif OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); } @@ -4386,9 +4464,9 @@ static const char *unixTempFileDir(void){ if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); for(i=0; ih, &buf) ){ + if( osFstat(conchFile->h, &buf) ){ pFile->lastErrno = errno; return SQLITE_IOERR_LOCK; } @@ -5807,7 +5885,7 @@ static int proxyTakeConch(unixFile *pFile){ if( rc==SQLITE_OK && createConch ){ struct stat buf; int rc; - int err = fstat(pFile->h, &buf); + int err = osFstat(pFile->h, &buf); if( err==0 ){ mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH); @@ -5842,7 +5920,7 @@ static int proxyTakeConch(unixFile *pFile){ robust_close(pFile, pFile->h, __LINE__) ){ } pFile->h = -1; - int fd = open(pCtx->dbPath, pFile->openFlags, + int fd = osOpen(pCtx->dbPath, pFile->openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ @@ -6068,7 +6146,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { struct stat conchInfo; int goLockless = 0; - if( stat(pCtx->conchFilePath, &conchInfo) == -1 ) { + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { int err = errno; if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; @@ -6353,7 +6431,7 @@ int sqlite3_os_init(void){ ** that filesystem time. */ #define UNIXVFS(VFSNAME, FINDER) { \ - 2, /* iVersion */ \ + 3, /* iVersion */ \ sizeof(unixFile), /* szOsFile */ \ MAX_PATHNAME, /* mxPathname */ \ 0, /* pNext */ \ @@ -6372,6 +6450,7 @@ int sqlite3_os_init(void){ unixCurrentTime, /* xCurrentTime */ \ unixGetLastError, /* xGetLastError */ \ unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ + unixSetSystemCall, /* xSetSystemCall */ \ } /* diff --git a/src/os_win.c b/src/os_win.c index 70425178e8..4d19e57a36 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2746,7 +2746,7 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ */ int sqlite3_os_init(void){ static sqlite3_vfs winVfs = { - 2, /* iVersion */ + 3, /* iVersion */ sizeof(winFile), /* szOsFile */ MAX_PATH, /* mxPathname */ 0, /* pNext */ @@ -2765,6 +2765,7 @@ int sqlite3_os_init(void){ winCurrentTime, /* xCurrentTime */ winGetLastError, /* xGetLastError */ winCurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ }; #ifndef SQLITE_OMIT_WAL diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3400c6c916..5c07b8d96a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -896,7 +896,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; */ typedef struct sqlite3_vfs sqlite3_vfs; struct sqlite3_vfs { - int iVersion; /* Structure version number (currently 2) */ + int iVersion; /* Structure version number (currently 3) */ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ @@ -922,6 +922,11 @@ struct sqlite3_vfs { int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, void *pFunc); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. ** New fields may be appended in figure versions. The iVersion ** value will increment whenever this happens. */ From befd5f3c20826aecaa19d32bcba69de8811150aa Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Mar 2011 15:44:35 +0000 Subject: [PATCH 03/35] Make sure the rtreenode() testing and analysis routine in the RTREE extension can handle 64-bit rowids. This fix is in response to a message on the mailing list. FossilOrigin-Name: 24602557fc3295fe2836d269175f12ec680ac011 --- ext/rtree/rtree.c | 2 +- ext/rtree/rtreeB.test | 34 ++++++++++++++++++++++++++++++++++ manifest | 19 ++++++++++--------- manifest.uuid | 2 +- 4 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 ext/rtree/rtreeB.test diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 5665e6aa8c..d47c1092ef 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3133,7 +3133,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ int jj; nodeGetCell(&tree, &node, ii, &cell); - sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid); + sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); nCell = strlen(zCell); for(jj=0; jj Date: Wed, 2 Mar 2011 17:54:32 +0000 Subject: [PATCH 04/35] Fix bugs in [7b6e30e6a7] that only show up on Mac. FossilOrigin-Name: ec55e8c6bb4f2419b3813aa2fd1a20d8f5016159 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os_unix.c | 3 +-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 46ea7a2a31..7bf2741a7b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Make\ssure\sthe\srtreenode()\stesting\sand\sanalysis\sroutine\sin\sthe\sRTREE\sextension\ncan\shandle\s64-bit\srowids.\s\sThis\sfix\sis\sin\sresponse\sto\sa\smessage\son\sthe\nmailing\slist. -D 2011-03-02T15:44:35.295 +C Fix\sbugs\sin\s[7b6e30e6a7]\sthat\sonly\sshow\sup\son\sMac. +D 2011-03-02T17:54:32.411 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 -F src/os_unix.c 5e2e1187c19cc20798dd9a08bee841fab0929ccf +F src/os_unix.c 54cd8b64e342984cb9a565d8bbd3d4ed4f6679ad F src/os_win.c 9abdcdd925416d854eabb0996c96debd92abfef5 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -913,14 +913,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 7b6e30e6a712311d4ef275253b085b85e6e17116 -R 63d565910eebcf96c11d56306627df7f +P 24602557fc3295fe2836d269175f12ec680ac011 +R e01d9f9e8e2dad85147f5fc5ffb976eb U drh -Z 2af12a98c29451d1c2b224c4c90f7e19 +Z c84f9d0b8eefba981fbaf57340fff3b5 -----BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) +Version: GnuPG v1.4.10 (Darwin) -iD8DBQFNbmXmoxKgR168RlERAimaAKCH0J+I0G9ZlKd6ou2sHa7StAeC+ACfdyUs -jKzM30hw9LfKyEheuhtOkXg= -=RSS1 +iEYEARECAAYFAk1uhFgACgkQoxKgR168RlFREQCfT9Vnfu+FKv7ziCX9Y4ICLtOr +MgsAnjKkrrgDNYH+MAY+dZUejwVsARq0 +=k7I4 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index df263e3814..eb42b9f72d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24602557fc3295fe2836d269175f12ec680ac011 \ No newline at end of file +ec55e8c6bb4f2419b3813aa2fd1a20d8f5016159 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index b70e2736bd..40e4b89cd6 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5806,7 +5806,6 @@ static int proxyTakeConch(unixFile *pFile){ */ if( rc==SQLITE_OK && createConch ){ struct stat buf; - int rc; int err = fstat(pFile->h, &buf); if( err==0 ){ mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | @@ -5839,7 +5838,7 @@ static int proxyTakeConch(unixFile *pFile){ OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); if( rc==SQLITE_OK && pFile->openFlags ){ if( pFile->h>=0 ){ - robust_close(pFile, pFile->h, __LINE__) ){ + robust_close(pFile, pFile->h, __LINE__); } pFile->h = -1; int fd = open(pCtx->dbPath, pFile->openFlags, From 1df30967af1a3e2c63d7863b26f544b44bd750ae Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Mar 2011 19:06:42 +0000 Subject: [PATCH 05/35] Add additional VFS methods to retrieve system call pointers and to get a list of all changeable system calls. FossilOrigin-Name: 38558363494e3a736dcb091dd859e76b7ccd78b0 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/os_unix.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- src/os_win.c | 2 ++ src/sqlite.h.in | 2 ++ 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 8febb8aa67..615bc1ff8d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\smore\ssystem\scalls\sto\sthe\sset\sthat\scan\sbe\soverridden\sin\sos_unix.c.\nAlso\smerge\sin\srecent\sfixes\sfrom\strunk. -D 2011-03-02T18:01:10.609 +C Add\sadditional\sVFS\smethods\sto\sretrieve\ssystem\scall\spointers\sand\sto\sget\sa\nlist\sof\sall\schangeable\ssystem\scalls. +D 2011-03-02T19:06:42.724 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,8 +165,8 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 -F src/os_unix.c a13aa2394c337a51f818b33e8abb5922bcd25cbb -F src/os_win.c c2df806a8510ec8c2c2c30fb78b3a25bc1b2f325 +F src/os_unix.c 3d38767952d504486d182dea7b77279688011896 +F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -181,7 +181,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in a2115e725e77ea1284a4df51b39f94121f020ab8 +F src/sqlite.h.in 660a7db4b052f0e390842fcaae49e3de5e10194d F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 4290fff17fabc6e07fc4338233df0e39e6350ca1 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 @@ -913,14 +913,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 92b5a76abc53290e1bb87b6b55bc64bb1b331dfc ec55e8c6bb4f2419b3813aa2fd1a20d8f5016159 -R 3565d6dc7b759fbd44b8dfd37d76ad07 +P 80fac2a6e07221bb67613af84ab9dda3e18b5ceb +R 469544ed72ad6cc0fd2ce66bb41ae458 U drh -Z d880c71a14ae5250c2798782141ecbce +Z 4fd425550526c290567641a06db348a6 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNboXpoxKgR168RlERAi5qAJ48oWmqxPjfRV4pFj4iAbQCs6u9fQCeNLi2 -M/sSIPhA4/GCd6qHTyrGyKQ= -=Ttvh +iD8DBQFNbpVGoxKgR168RlERAiVlAJ9CbY/F1l/3wLXTOWVbVMt3PK4e2wCfXCEX +gkP0SmX/m93Upo7bU9m9XaA= +=DBkJ -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 3647910982..0f06d09f05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80fac2a6e07221bb67613af84ab9dda3e18b5ceb \ No newline at end of file +38558363494e3a736dcb091dd859e76b7ccd78b0 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 18ec658701..c5261bb111 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -376,7 +376,9 @@ static struct unix_syscall { /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "unix" VFSes. +** "unix" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. */ static int unixSetSystemCall( sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ @@ -384,7 +386,7 @@ static int unixSetSystemCall( void *pNewFunc /* Pointer to new system call value */ ){ int i; - int rc = 0; + int rc = SQLITE_NOTFOUND; if( zName==0 ){ /* If no zName is given, restore all system calls to their default ** settings and return NULL @@ -392,7 +394,7 @@ static int unixSetSystemCall( for(i=0; i Date: Wed, 2 Mar 2011 22:07:29 +0000 Subject: [PATCH 06/35] Fix quoting of the result in rtreeB.test. FossilOrigin-Name: c6532b35cc5a81cc753a22e0165bfdd5143941f1 --- ext/rtree/rtreeB.test | 2 +- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/rtree/rtreeB.test b/ext/rtree/rtreeB.test index 98c9c2b1ff..2756fceedb 100644 --- a/ext/rtree/rtreeB.test +++ b/ext/rtree/rtreeB.test @@ -28,7 +28,7 @@ do_test rtreeB-1.1 { INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400); SELECT rtreenode(2, data) FROM t1_node; } -} {{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}} +} {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}} finish_test diff --git a/manifest b/manifest index 7bf2741a7b..eb8af982a5 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\sbugs\sin\s[7b6e30e6a7]\sthat\sonly\sshow\sup\son\sMac. -D 2011-03-02T17:54:32.411 +C Fix\squoting\sof\sthe\sresult\sin\srtreeB.test. +D 2011-03-02T22:07:29.984 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -96,7 +96,7 @@ F ext/rtree/rtree7.test bcb647b42920b3b5d025846689147778485cc318 F ext/rtree/rtree8.test 9772e16da71e17e02bdebf0a5188590f289ab37d F ext/rtree/rtree9.test df9843d1a9195249c8d3b4ea6aedda2d5c73e9c2 F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf -F ext/rtree/rtreeB.test cd45c955cd35a325545671723255f71f2ae9c2e7 +F ext/rtree/rtreeB.test b1916a9cecb86b02529c4cc5a546e8d6e7ff10da F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 @@ -913,14 +913,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 24602557fc3295fe2836d269175f12ec680ac011 -R e01d9f9e8e2dad85147f5fc5ffb976eb +P ec55e8c6bb4f2419b3813aa2fd1a20d8f5016159 +R 4466b84201cf07d8b58b7f3df32e8610 U drh -Z c84f9d0b8eefba981fbaf57340fff3b5 +Z e51cd0af4553d3bdc1671b46c3024fc0 -----BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.10 (Darwin) +Version: GnuPG v1.4.6 (GNU/Linux) -iEYEARECAAYFAk1uhFgACgkQoxKgR168RlFREQCfT9Vnfu+FKv7ziCX9Y4ICLtOr -MgsAnjKkrrgDNYH+MAY+dZUejwVsARq0 -=k7I4 +iD8DBQFNbr+loxKgR168RlERAifFAJ4rxcZg2GHVUmhY14d6bC3+WoLAOQCfYvQK +lkhmZIcwz4BBbhXLINTF0CM= +=JloW -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index eb42b9f72d..94178786c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec55e8c6bb4f2419b3813aa2fd1a20d8f5016159 \ No newline at end of file +c6532b35cc5a81cc753a22e0165bfdd5143941f1 \ No newline at end of file From 92e4feb74c888c323d5960861b12d260e774ea45 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Mar 2011 00:56:58 +0000 Subject: [PATCH 07/35] Do a better job of choosing the join table order when the tables having very different numbers of rows. FossilOrigin-Name: 952f5e8c69904c48f2decfabf8ea60a2e9f3e134 --- manifest | 19 ++++++------ manifest.uuid | 2 +- src/where.c | 5 ++-- test/analyze6.test | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 test/analyze6.test diff --git a/manifest b/manifest index eb8af982a5..fe1dc68240 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\squoting\sof\sthe\sresult\sin\srtreeB.test. -D 2011-03-02T22:07:29.984 +C Do\sa\sbetter\sjob\sof\schoosing\sthe\sjoin\stable\sorder\swhen\sthe\stables\shaving\nvery\sdifferent\snumbers\sof\srows. +D 2011-03-04T00:56:58.067 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -245,7 +245,7 @@ F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 5386fb5e13c2daa8ab9062597fdc17bd849da371 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c bf8c0f584a2c9becb9110c37e151f9d4f73fbf7e +F src/where.c d7b073867e7bab0b851c659ad4899ce72cc9b81d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125 @@ -259,6 +259,7 @@ F test/analyze2.test 8f2b1534d43f5547ce9a6b736c021d4192c75be3 F test/analyze3.test d61f55d8b472fc6e713160b1e577f7a68e63f38b F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 F test/analyze5.test 0618d2fe8982a5dae1d4e92152acc8ecbaf52be2 +F test/analyze6.test 1ba1aea8fad25a77ffd71f24522d1bb9ecc949fc F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3 F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6 F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e @@ -913,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ec55e8c6bb4f2419b3813aa2fd1a20d8f5016159 -R 4466b84201cf07d8b58b7f3df32e8610 +P c6532b35cc5a81cc753a22e0165bfdd5143941f1 +R a3d7e872cd52f3bb8cff4bf51476ab7a U drh -Z e51cd0af4553d3bdc1671b46c3024fc0 +Z 87aba3dd3051578a2e8c32390f315773 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNbr+loxKgR168RlERAifFAJ4rxcZg2GHVUmhY14d6bC3+WoLAOQCfYvQK -lkhmZIcwz4BBbhXLINTF0CM= -=JloW +iD8DBQFNcDjeoxKgR168RlERAn2TAJ9XKohvD0kx5t1CAQmiI1sUD+1b8QCdFh0P +RilThkZz6kdLZmkRZY4ir5s= +=inuw -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 94178786c0..b5f246c15a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6532b35cc5a81cc753a22e0165bfdd5143941f1 \ No newline at end of file +952f5e8c69904c48f2decfabf8ea60a2e9f3e134 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9ad2ad3202..727abdf3f6 100644 --- a/src/where.c +++ b/src/where.c @@ -4610,8 +4610,8 @@ WhereInfo *sqlite3WhereBegin( ** (1) The table must not depend on other tables that have not ** yet run. ** - ** (2) A full-table-scan plan cannot supercede another plan unless - ** it is an "optimal" plan as defined above. + ** (2) A full-table-scan plan cannot supercede indexed plan unless + ** the full-table-scan is an "optimal" plan as defined above. ** ** (3) All tables have an INDEXED BY clause or this table lacks an ** INDEXED BY clause or this table uses the specific @@ -4627,6 +4627,7 @@ WhereInfo *sqlite3WhereBegin( */ if( (sCost.used¬Ready)==0 /* (1) */ && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ + || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) && (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */ || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) diff --git a/test/analyze6.test b/test/analyze6.test new file mode 100644 index 0000000000..515747cbfc --- /dev/null +++ b/test/analyze6.test @@ -0,0 +1,74 @@ +# 2011 March 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 tests for SQLite library. The focus of the tests +# in this file a corner-case query planner optimization involving the +# join order of two tables of different sizes. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !stat2 { + finish_test + return +} + +set testprefix analyze6 + +proc eqp {sql {db db}} { + uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db +} + +do_test analyze6-1.0 { + db eval { + CREATE TABLE cat(x INT); + CREATE UNIQUE INDEX catx ON cat(x); + /* Give cat 16 unique integers */ + INSERT INTO cat VALUES(1); + INSERT INTO cat VALUES(2); + INSERT INTO cat SELECT x+2 FROM cat; + INSERT INTO cat SELECT x+4 FROM cat; + INSERT INTO cat SELECT x+8 FROM cat; + + CREATE TABLE ev(y INT); + CREATE INDEX evy ON ev(y); + /* ev will hold 32 copies of 16 integers found in cat */ + INSERT INTO ev SELECT x FROM cat; + INSERT INTO ev SELECT x FROM cat; + INSERT INTO ev SELECT y FROM ev; + INSERT INTO ev SELECT y FROM ev; + INSERT INTO ev SELECT y FROM ev; + INSERT INTO ev SELECT y FROM ev; + ANALYZE; + SELECT count(*) FROM cat; + SELECT count(*) FROM ev; + } +} {16 512} + +# The lowest cost plan is to scan CAT and for each integer there, do a single +# lookup of the first corresponding entry in EV then read off the equal values +# in EV. (Prior to the 2011-03-04 enhancement to where.c, this query would +# have used EV for the outer loop instead of CAT - which was about 3x slower.) +# +do_test analyze6-1.1 { + eqp {SELECT count(*) FROM ev, cat WHERE x=y} +} {0 0 1 {SCAN TABLE cat (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}} + +# The same plan is chosen regardless of the order of the tables in the +# FROM clause. +# +do_test analyze6-1.2 { + eqp {SELECT count(*) FROM cat, ev WHERE x=y} +} {0 0 0 {SCAN TABLE cat (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}} + + +finish_test From ad4f1e5415172118296cc05f76857f79a7286c65 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Mar 2011 15:43:57 +0000 Subject: [PATCH 08/35] Handle EINTR errors from open(). FossilOrigin-Name: a7d176b27cd73791d45eb3a31df78187ae10ce20 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/os_unix.c | 38 +++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 615bc1ff8d..a064a0b5e5 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\sadditional\sVFS\smethods\sto\sretrieve\ssystem\scall\spointers\sand\sto\sget\sa\nlist\sof\sall\schangeable\ssystem\scalls. -D 2011-03-02T19:06:42.724 +C Handle\sEINTR\serrors\sfrom\sopen(). +D 2011-03-04T15:43:57.699 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 -F src/os_unix.c 3d38767952d504486d182dea7b77279688011896 +F src/os_unix.c cb94e52f705b8e0ae2b2ddd387f71d6c4e08cd71 F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -913,14 +913,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 80fac2a6e07221bb67613af84ab9dda3e18b5ceb -R 469544ed72ad6cc0fd2ce66bb41ae458 +P 38558363494e3a736dcb091dd859e76b7ccd78b0 +R dd2dabc15bf7d4925fef6d097c8b1859 U drh -Z 4fd425550526c290567641a06db348a6 +Z 534640ef6b55077422a57e880c660f80 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNbpVGoxKgR168RlERAiVlAJ9CbY/F1l/3wLXTOWVbVMt3PK4e2wCfXCEX -gkP0SmX/m93Upo7bU9m9XaA= -=DBkJ +iD8DBQFNcQjAoxKgR168RlERAg0SAJ9rCSURrs0OHohp+icweWOPgtvSxQCdHnS5 +3mAQcVk63NipJkS+azKbo50= +=vPdf -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 0f06d09f05..49190d1535 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38558363494e3a736dcb091dd859e76b7ccd78b0 \ No newline at end of file +a7d176b27cd73791d45eb3a31df78187ae10ce20 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index c5261bb111..79038a5846 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -450,6 +450,14 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){ return 0; } +/* +** Retry open() calls that fail due to EINTR +*/ +static int robust_open(const char *z, int f, int m){ + int rc; + do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR ); + return rc; +} /* ** Helper functions to obtain and relinquish the global mutex. The @@ -556,20 +564,14 @@ static int lockTrace(int fd, int op, struct flock *p){ #define osFcntl lockTrace #endif /* SQLITE_LOCK_TRACE */ - /* ** Retry ftruncate() calls that fail due to EINTR */ -#ifdef EINTR static int robust_ftruncate(int h, sqlite3_int64 sz){ int rc; do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); return rc; } -#else -# define robust_ftruncate(a,b) osFtruncate(a,b) -#endif - /* ** This routine translates a standard POSIX errno code into something @@ -1861,7 +1863,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } /* grab an exclusive lock */ - fd = osOpen(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); + fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); if( fd<0 ){ /* failed to open/create the file, someone else may have stolen the lock */ int tErrno = errno; @@ -3686,7 +3688,8 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ goto shm_open_err; } - pShmNode->h = osOpen(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777)); + pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, + (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); goto shm_open_err; @@ -4514,7 +4517,7 @@ static int openDirectory(const char *zFilename, int *pFd){ for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; - fd = osOpen(zDirname, O_RDONLY|O_BINARY, 0); + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); if( fd>=0 ){ #ifdef FD_CLOEXEC osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); @@ -4853,7 +4856,7 @@ static int unixOpen( assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); return rc; } - fd = osOpen(zName, openFlags, openMode); + fd = robust_open(zName, openFlags, openMode); OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ /* Failed to open the file for read/write access. Try read-only. */ @@ -4861,7 +4864,7 @@ static int unixOpen( openFlags &= ~(O_RDWR|O_CREAT); flags |= SQLITE_OPEN_READONLY; openFlags |= O_RDONLY; - fd = osOpen(zName, openFlags, openMode); + fd = robust_open(zName, openFlags, openMode); } if( fd<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); @@ -5188,7 +5191,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ #if !defined(SQLITE_TEST) { int pid, fd; - fd = osOpen("/dev/urandom", O_RDONLY, 0); + fd = robust_open("/dev/urandom", O_RDONLY, 0); if( fd<0 ){ time_t t; time(&t); @@ -5597,17 +5600,17 @@ static int proxyCreateUnixFile( } } if( fd<0 ){ - fd = osOpen(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); terrno = errno; if( fd<0 && errno==ENOENT && islockfile ){ if( proxyCreateLockPath(path) == SQLITE_OK ){ - fd = osOpen(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); } } } if( fd<0 ){ openFlags = O_RDONLY; - fd = osOpen(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); terrno = errno; } if( fd<0 ){ @@ -5727,7 +5730,8 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ goto end_breaklock; } /* write it out to the temporary break file */ - fd = osOpen(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), + SQLITE_DEFAULT_FILE_PERMISSIONS); if( fd<0 ){ sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno); goto end_breaklock; @@ -6002,7 +6006,7 @@ static int proxyTakeConch(unixFile *pFile){ robust_close(pFile, pFile->h, __LINE__); } pFile->h = -1; - int fd = osOpen(pCtx->dbPath, pFile->openFlags, + int fd = robust_open(pCtx->dbPath, pFile->openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ From cfd654bf2a3a2f546a3a4507ca196be97f2a37a1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 5 Mar 2011 13:54:15 +0000 Subject: [PATCH 09/35] Fix an instance of signed arithmetic overflow and an one bit-shift overflow. Mark six other signed arithmetic overflow locations that need fixing. FossilOrigin-Name: 04abab71ecd52f6070b9f84781a3df3d6dba7722 --- install-sh | 0 manifest | 36 ++++++++++++++++++------------------ manifest.uuid | 2 +- src/expr.c | 2 +- src/func.c | 2 +- src/printf.c | 2 +- src/update.c | 2 +- src/util.c | 4 ++-- src/vdbe.c | 2 +- src/vdbeaux.c | 8 +++++++- test/progress.test | 0 tool/mkopts.tcl | 0 12 files changed, 33 insertions(+), 27 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index fe1dc68240..e8bdbb82a6 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Do\sa\sbetter\sjob\sof\schoosing\sthe\sjoin\stable\sorder\swhen\sthe\stables\shaving\nvery\sdifferent\snumbers\sof\srows. -D 2011-03-04T00:56:58.067 +C Fix\san\sinstance\sof\ssigned\sarithmetic\soverflow\sand\san\sone\sbit-shift\soverflow.\nMark\ssix\sother\ssigned\sarithmetic\soverflow\slocations\sthat\sneed\sfixing. +D 2011-03-05T13:54:15.956 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk 54190fab7cdba523e311c274c95ea480f32abfb5 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -133,10 +133,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd -F src/expr.c 8e2c607b3be87a35c75a1f5dac50c10666b083c0 +F src/expr.c 0afd6a93d95614e57b29d1c6da5f74be5a4d4fbd F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a -F src/func.c cb41f614edc43b00bfeb030f9768e80eaff47edd +F src/func.c 9b88e09d238eecdb6242bd387901e6d9f7f64531 F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -175,7 +175,7 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1 F src/prepare.c 395b3fab1b93f45b6aa194b23ebc201221c47b99 -F src/printf.c df2ff3bb5409e8958136933342c46464fbd017e7 +F src/printf.c 6eb5c70b531464cca4254e70aaafdf2e7da3a743 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 @@ -229,15 +229,15 @@ F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 -F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 +F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c ab1c92426494f499f42b9e307537b03e923d75c1 +F src/util.c 77572d1f37c5b319d9e735c745349304791f7ba5 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 34305497d81daafdb1e500bfaa21d044c64503de +F src/vdbe.c 953d44f0fbd72bf73a278c10e7bdd9164235260d F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0 F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d -F src/vdbeaux.c 5936a596324ad9f9aba02bdee8c8080d2a3264e1 +F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -602,7 +602,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -889,7 +889,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P c6532b35cc5a81cc753a22e0165bfdd5143941f1 -R a3d7e872cd52f3bb8cff4bf51476ab7a +P 952f5e8c69904c48f2decfabf8ea60a2e9f3e134 +R c0946fb5d31ae3d41275b61febc12359 U drh -Z 87aba3dd3051578a2e8c32390f315773 +Z 4b81d66afc295ddd153d99c651678bf2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNcDjeoxKgR168RlERAn2TAJ9XKohvD0kx5t1CAQmiI1sUD+1b8QCdFh0P -RilThkZz6kdLZmkRZY4ir5s= -=inuw +iD8DBQFNckCLoxKgR168RlERAq5MAJwIkQItYpj2jIMbedpVkYZIN7SirACePysg +Jf8UO88YpxqtY86joGQ7FqQ= +=f5iN -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index b5f246c15a..ad8d2b9252 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -952f5e8c69904c48f2decfabf8ea60a2e9f3e134 \ No newline at end of file +04abab71ecd52f6070b9f84781a3df3d6dba7722 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b7b73946cd..57243c74e8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1964,7 +1964,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); if( c==0 || (c==2 && negFlag) ){ char *zV; - if( negFlag ){ value = -value; } + if( negFlag ){ value = -value; } /* CLANG */ zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); }else{ diff --git a/src/func.c b/src/func.c index 19c6d22510..2f21ac0e3d 100644 --- a/src/func.c +++ b/src/func.c @@ -1240,7 +1240,7 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ i64 v = sqlite3_value_int64(argv[0]); p->rSum += v; if( (p->approx|p->overflow)==0 ){ - i64 iNewSum = p->iSum + v; + i64 iNewSum = p->iSum + v; /* CLANG */ int s1 = (int)(p->iSum >> (sizeof(i64)*8-1)); int s2 = (int)(v >> (sizeof(i64)*8-1)); int s3 = (int)(iNewSum >> (sizeof(i64)*8-1)); diff --git a/src/printf.c b/src/printf.c index c88bb30006..21b6c0e11a 100644 --- a/src/printf.c +++ b/src/printf.c @@ -400,7 +400,7 @@ void sqlite3VXPrintf( v = va_arg(ap,int); } if( v<0 ){ - longvalue = -v; + longvalue = -v; /* CLANG */ prefix = '-'; }else{ longvalue = v; diff --git a/src/update.c b/src/update.c index 8bf58d7666..045b4d176d 100644 --- a/src/update.c +++ b/src/update.c @@ -396,7 +396,7 @@ void sqlite3Update( pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError ); for(i=0; inCol; i++){ - if( aXRef[i]<0 || oldmask==0xffffffff || (oldmask & (1<='0' && c<='9'; i+=incr){ - v = v*10 + c - '0'; + v = v*10 + c - '0'; /* CLANG */ } - *pNum = neg ? -v : v; + *pNum = neg ? -v : v; /* CLANG */ testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); diff --git a/src/vdbe.c b/src/vdbe.c index 00ed1438b5..3a7397687b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1246,7 +1246,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ iA = pIn1->u.i; iB = pIn2->u.i; switch( pOp->opcode ){ - case OP_Add: iB += iA; break; + case OP_Add: iB += iA; break; /* CLANG */ case OP_Subtract: iB -= iA; break; case OP_Multiply: iB *= iA; break; case OP_Divide: { diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 64ff489919..4a1b1efbb2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2497,7 +2497,13 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ if( file_format>=4 && (i&1)==i ){ return 8+(u32)i; } - u = i<0 ? -i : i; + if( i<0 ){ + if( i<(-MAX_6BYTE) ) return 6; + /* Previous test prevents: u = -(-9223372036854775808) */ + u = -i; + }else{ + u = i; + } if( u<=127 ) return 1; if( u<=32767 ) return 2; if( u<=8388607 ) return 3; diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From 158b9cb965519d7f8d3e4d5f6c45bce842fc51d4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 5 Mar 2011 20:59:46 +0000 Subject: [PATCH 10/35] Fix all known instances of signed-integer overflow. Within SQL expressions, integer overflow now forces coercion to floating point. The shift operators work with any integer right-hand operand with negative values reversing the direction of the shift. FossilOrigin-Name: abf21394124a0af46f072793718964cee2ce55d0 --- manifest | 32 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- src/func.c | 9 +--- src/printf.c | 6 ++- src/sqliteInt.h | 3 ++ src/util.c | 128 +++++++++++++++++++++++++++++++++++++++--------- src/vdbe.c | 62 ++++++++++++++--------- src/vdbemem.c | 2 +- test/expr.test | 119 ++++++++++++++++++++++++++++++++++++++++++-- 10 files changed, 288 insertions(+), 77 deletions(-) diff --git a/manifest b/manifest index e8bdbb82a6..c596f893ae 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\san\sinstance\sof\ssigned\sarithmetic\soverflow\sand\san\sone\sbit-shift\soverflow.\nMark\ssix\sother\ssigned\sarithmetic\soverflow\slocations\sthat\sneed\sfixing. -D 2011-03-05T13:54:15.956 +C Fix\sall\sknown\sinstances\sof\ssigned-integer\soverflow.\s\sWithin\sSQL\sexpressions,\ninteger\soverflow\snow\sforces\scoercion\sto\sfloating\spoint.\s\sThe\sshift\soperators\nwork\swith\sany\sinteger\sright-hand\soperand\swith\snegative\svalues\sreversing\nthe\sdirection\sof\sthe\sshift. +D 2011-03-05T20:59:46.394 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -133,10 +133,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd -F src/expr.c 0afd6a93d95614e57b29d1c6da5f74be5a4d4fbd +F src/expr.c 66c9383e5e1f5259c43ef3aa7883da66cfc0f492 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a -F src/func.c 9b88e09d238eecdb6242bd387901e6d9f7f64531 +F src/func.c 3a8cb2fb2de3e3aed7f39106daf4878d9d17fcce F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -175,7 +175,7 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1 F src/prepare.c 395b3fab1b93f45b6aa194b23ebc201221c47b99 -F src/printf.c 6eb5c70b531464cca4254e70aaafdf2e7da3a743 +F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 @@ -183,7 +183,7 @@ F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 4290fff17fabc6e07fc4338233df0e39e6350ca1 +F src/sqliteInt.h 118481da7db00c4ae2709ed8af6498be900e6ae0 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -231,15 +231,15 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c 77572d1f37c5b319d9e735c745349304791f7ba5 +F src/util.c c849a1e77d00a8a28429a22818155dbf9c311fee F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 953d44f0fbd72bf73a278c10e7bdd9164235260d +F src/vdbe.c 038e5689e48cd6597158c5dc34f8d40a03a87ad7 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0 F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c -F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50 +F src/vdbemem.c d8f713bcc3e176040d3e2bb4fbffc3b31faa4252 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 5386fb5e13c2daa8ab9062597fdc17bd849da371 @@ -383,7 +383,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062 F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 -F test/expr.test 620a636cf7b7d4e5834a0b9d83a4da372e24a7b7 +F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6 F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e F test/filefmt.test f178cfc29501a14565954c961b226e61877dd32c @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 952f5e8c69904c48f2decfabf8ea60a2e9f3e134 -R c0946fb5d31ae3d41275b61febc12359 +P 04abab71ecd52f6070b9f84781a3df3d6dba7722 +R dffbfc883d2df8713fd0ba30b453b561 U drh -Z 4b81d66afc295ddd153d99c651678bf2 +Z e566f37c8f9e6003556e493773a7db62 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNckCLoxKgR168RlERAq5MAJwIkQItYpj2jIMbedpVkYZIN7SirACePysg -Jf8UO88YpxqtY86joGQ7FqQ= -=f5iN +iD8DBQFNcqRGoxKgR168RlERAlK6AJ9gnf6EDR2ZKhaKkoiA1Nkl5MKeDgCeOJxY +dz92w6QJZQImuyiplDh238s= +=sTB2 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index ad8d2b9252..6a05b41f73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04abab71ecd52f6070b9f84781a3df3d6dba7722 \ No newline at end of file +abf21394124a0af46f072793718964cee2ce55d0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 57243c74e8..b938d9657b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1964,7 +1964,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); if( c==0 || (c==2 && negFlag) ){ char *zV; - if( negFlag ){ value = -value; } /* CLANG */ + if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); }else{ diff --git a/src/func.c b/src/func.c index 2f21ac0e3d..6a4f7c09c3 100644 --- a/src/func.c +++ b/src/func.c @@ -1239,13 +1239,8 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ if( type==SQLITE_INTEGER ){ i64 v = sqlite3_value_int64(argv[0]); p->rSum += v; - if( (p->approx|p->overflow)==0 ){ - i64 iNewSum = p->iSum + v; /* CLANG */ - int s1 = (int)(p->iSum >> (sizeof(i64)*8-1)); - int s2 = (int)(v >> (sizeof(i64)*8-1)); - int s3 = (int)(iNewSum >> (sizeof(i64)*8-1)); - p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0; - p->iSum = iNewSum; + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ + p->overflow = 1; } }else{ p->rSum += sqlite3_value_double(argv[0]); diff --git a/src/printf.c b/src/printf.c index 21b6c0e11a..2a3dd81d7d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -400,7 +400,11 @@ void sqlite3VXPrintf( v = va_arg(ap,int); } if( v<0 ){ - longvalue = -v; /* CLANG */ + if( v==SMALLEST_INT64 ){ + longvalue = ((u64)1)<<63; + }else{ + longvalue = -v; + } prefix = '-'; }else{ longvalue = v; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2987dcd483..bbf1b16883 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2903,6 +2903,9 @@ Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3CheckObjectName(Parse *, const char *); void sqlite3VdbeSetChanges(sqlite3 *, int); +int sqlite3AddInt64(i64*,i64); +int sqlite3SubInt64(i64*,i64); +int sqlite3MulInt64(i64*,i64); const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8); diff --git a/src/util.c b/src/util.c index ca22749fa0..b2787974c1 100644 --- a/src/util.c +++ b/src/util.c @@ -441,14 +441,17 @@ static int compare2pow63(const char *zNum, int incr){ /* -** Convert zNum to a 64-bit signed integer and write -** the value of the integer into *pNum. -** If zNum is exactly 9223372036854665808, return 2. -** This is a special case as the context will determine -** if it is too big (used as a negative). -** If zNum is not an integer or is an integer that -** is too large to be expressed with 64 bits, -** then return 1. Otherwise return 0. +** Convert zNum to a 64-bit signed integer. +** +** If the zNum value is representable as a 64-bit twos-complement +** integer, then write that value into *pNum and return 0. +** +** If zNum is exactly 9223372036854665808, return 2. This special +** case is broken out because while 9223372036854665808 cannot be a +** signed 64-bit integer, its negative -9223372036854665808 can be. +** +** If zNum is too big for a 64-bit integer and is not +** 9223372036854665808 then return 1. ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is @@ -456,7 +459,7 @@ static int compare2pow63(const char *zNum, int incr){ */ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr = (enc==SQLITE_UTF8?1:2); - i64 v = 0; + u64 u = 0; int neg = 0; /* assume positive */ int i; int c = 0; @@ -464,20 +467,26 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ const char *zEnd = zNum + length; if( enc==SQLITE_UTF16BE ) zNum++; while( zNum=zEnd ) goto do_atoi_calc; - if( *zNum=='-' ){ - neg = 1; - zNum+=incr; - }else if( *zNum=='+' ){ - zNum+=incr; + if( zNum='0' && c<='9'; i+=incr){ - v = v*10 + c - '0'; /* CLANG */ + u = u*10 + c - '0'; + } + if( u>LARGEST_INT64 ){ + *pNum = SMALLEST_INT64; + }else if( neg ){ + *pNum = -(i64)u; + }else{ + *pNum = (i64)u; } - *pNum = neg ? -v : v; /* CLANG */ testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); @@ -487,14 +496,25 @@ do_atoi_calc: return 1; }else if( i<19*incr ){ /* Less than 19 digits, so we know that it fits in 64 bits */ + assert( u<=LARGEST_INT64 ); return 0; }else{ - /* 19-digit numbers must be no larger than 9223372036854775807 if positive - ** or 9223372036854775808 if negative. Note that 9223372036854665808 - ** is 2^63. Return 1 if to large */ - c=compare2pow63(zNum, incr); - if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */ - return c0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 1; + }else{ + /* zNum is exactly 9223372036854775808. Fits if negative. The + ** special case 2 overflow if positive */ + assert( u-1==LARGEST_INT64 ); + assert( (*pNum)==SMALLEST_INT64 ); + return neg ? 0 : 2; + } } } @@ -1060,3 +1080,63 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ return 1; } } + +/* +** Attempt to add, substract, or multiply the 64-bit signed value iB against +** the other 64-bit signed integer at *pA and store the result in *pA. +** Return 0 on success. Or if the operation would have resulted in an +** overflow, leave *pA unchanged and return 1. +*/ +int sqlite3AddInt64(i64 *pA, i64 iB){ + i64 iA = *pA; + testcase( iA==0 ); testcase( iA==1 ); + testcase( iB==-1 ); testcase( iB==0 ); + if( iB>=0 ){ + testcase( iA>0 && LARGEST_INT64 - iA == iB ); + testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); + if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; + *pA += iB; + }else{ + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); + if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; + *pA += iB; + } + return 0; +} +int sqlite3SubInt64(i64 *pA, i64 iB){ + testcase( iB==SMALLEST_INT64+1 ); + if( iB==SMALLEST_INT64 ){ + testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); + if( (*pA)>=0 ) return 1; + *pA -= iB; + return 0; + }else{ + return sqlite3AddInt64(pA, -iB); + } +} +#define TWOPOWER32 (((i64)1)<<32) +#define TWOPOWER31 (((i64)1)<<31) +int sqlite3MulInt64(i64 *pA, i64 iB){ + i64 iA = *pA; + i64 iA1, iA0, iB1, iB0, r; + +// if( iB==1 ){ return 0; } +// if( iA==1 ){ *pA = iB; return 0; } + iA1 = iA/TWOPOWER32; + iA0 = iA % TWOPOWER32; + iB1 = iB/TWOPOWER32; + iB0 = iB % TWOPOWER32; + if( iA1*iB1 != 0 ) return 1; + r = iA1*iB0; + if( sqlite3AddInt64(&r, iA0*iB1) ) return 1; + testcase( r==(-TWOPOWER31)-1 ); + testcase( r==(-TWOPOWER31) ); + testcase( r==TWOPOWER31 ); + testcase( r==TWOPOWER31-1 ); + if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1; + r *= TWOPOWER32; + if( sqlite3AddInt64(&r, iA0*iB0) ) return 1; + *pA = r; + return 0; +} diff --git a/src/vdbe.c b/src/vdbe.c index 3a7397687b..823688e797 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1246,19 +1246,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ iA = pIn1->u.i; iB = pIn2->u.i; switch( pOp->opcode ){ - case OP_Add: iB += iA; break; /* CLANG */ - case OP_Subtract: iB -= iA; break; - case OP_Multiply: iB *= iA; break; + case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; + case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; + case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; case OP_Divide: { if( iA==0 ) goto arithmetic_result_is_null; - /* Dividing the largest possible negative 64-bit integer (1<<63) by - ** -1 returns an integer too large to store in a 64-bit data-type. On - ** some architectures, the value overflows to (1<<63). On others, - ** a SIGFPE is issued. The following statement normalizes this - ** behavior so that all architectures behave as if integer - ** overflow occurred. - */ - if( iA==-1 && iB==SMALLEST_INT64 ) iA = 1; + if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; iB /= iA; break; } @@ -1272,6 +1265,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); }else{ +fp_math: rA = sqlite3VdbeRealValue(pIn1); rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ @@ -1466,8 +1460,10 @@ case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ - i64 a; - i64 b; + i64 iA; + u64 uA; + i64 iB; + u8 op; pIn1 = &aMem[pOp->p1]; pIn2 = &aMem[pOp->p2]; @@ -1476,16 +1472,38 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ sqlite3VdbeMemSetNull(pOut); break; } - a = sqlite3VdbeIntValue(pIn2); - b = sqlite3VdbeIntValue(pIn1); - switch( pOp->opcode ){ - case OP_BitAnd: a &= b; break; - case OP_BitOr: a |= b; break; - case OP_ShiftLeft: a <<= b; break; - default: assert( pOp->opcode==OP_ShiftRight ); - a >>= b; break; + iA = sqlite3VdbeIntValue(pIn2); + iB = sqlite3VdbeIntValue(pIn1); + op = pOp->opcode; + if( op==OP_BitAnd ){ + iA &= iB; + }else if( op==OP_BitOr ){ + iA |= iB; + }else if( iB!=0 ){ + assert( op==OP_ShiftRight || op==OP_ShiftLeft ); + + /* If shifting by a negative amount, shift in the other direction */ + if( iB<0 ){ + assert( OP_ShiftRight==OP_ShiftLeft+1 ); + op = 2*OP_ShiftLeft + 1 - op; + iB = iB>(-64) ? -iB : 64; + } + + if( iB>=64 ){ + iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1; + }else{ + memcpy(&uA, &iA, sizeof(uA)); + if( op==OP_ShiftLeft ){ + uA <<= iB; + }else{ + uA >>= iB; + /* Sign-extend on a right shift of a negative number */ + if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB); + } + memcpy(&iA, &uA, sizeof(iA)); + } } - pOut->u.i = a; + pOut->u.i = iA; MemSetTypeFlag(pOut, MEM_Int); break; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 104b93fd66..d2fdeb7ee9 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -367,7 +367,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ }else if( flags & MEM_Real ){ return doubleToInt64(pMem->r); }else if( flags & (MEM_Str|MEM_Blob) ){ - i64 value; + i64 value = 0; assert( pMem->z || pMem->n==0 ); testcase( pMem->z==0 ); sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); diff --git a/test/expr.test b/test/expr.test index 140ab8d8b3..5a3d167517 100644 --- a/test/expr.test +++ b/test/expr.test @@ -82,8 +82,18 @@ test_expr expr-1.43 {i1=1, i2=2} {i1&i2} {0} test_expr expr-1.43b {i1=1, i2=2} {4&5} {4} test_expr expr-1.44 {i1=1} {~i1} {-2} test_expr expr-1.44b {i1=NULL} {~i1} {{}} -test_expr expr-1.45 {i1=1, i2=3} {i1<>i2} {4} +test_expr expr-1.45a {i1=1, i2=3} {i1<>i2} {8} +test_expr expr-1.45c {i1=1, i2=0} {i1<>i2} {0} +test_expr expr-1.46a {i1=32, i2=3} {i1>>i2} {4} +test_expr expr-1.46b {i1=32, i2=6} {i1>>i2} {0} +test_expr expr-1.46c {i1=-32, i2=3} {i1>>i2} {-4} +test_expr expr-1.46d {i1=-32, i2=100} {i1>>i2} {-1} +test_expr expr-1.46e {i1=32, i2=-3} {i1>>i2} {256} test_expr expr-1.47 {i1=9999999999, i2=8888888888} {i1i2} 1 @@ -154,10 +164,10 @@ ifcapable floatingpoint { } if {[working_64bit_int]} { - test_expr expr-1.106 {i1=0} {(1<<63)/-1} -9223372036854775808 + test_expr expr-1.106 {i1=0} {-9223372036854775808/-1} 9.22337203685478e+18 } -test_expr expr-1.107 {i1=0} {(1<<63)%-1} 0 +test_expr expr-1.107 {i1=0} {-9223372036854775808%-1} 0 test_expr expr-1.108 {i1=0} {1%0} {{}} test_expr expr-1.109 {i1=0} {1/0} {{}} @@ -190,6 +200,107 @@ test_expr expr-1.125 {i1=6, i2=NULL} \ test_expr expr-1.126 {i1=8, i2=8} \ {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no +ifcapable floatingpoint {if {[working_64bit_int]} { + test_expr expr-1.200\ + {i1=9223372036854775806, i2=1} {i1+i2} 9223372036854775807 + test_expr expr-1.201\ + {i1=9223372036854775806, i2=2} {i1+i2} 9.22337203685478e+18 + test_expr expr-1.202\ + {i1=9223372036854775806, i2=100000} {i1+i2} 9.22337203685488e+18 + test_expr expr-1.203\ + {i1=9223372036854775807, i2=0} {i1+i2} 9223372036854775807 + test_expr expr-1.204\ + {i1=9223372036854775807, i2=1} {i1+i2} 9.22337203685478e+18 + test_expr expr-1.205\ + {i2=9223372036854775806, i1=1} {i1+i2} 9223372036854775807 + test_expr expr-1.206\ + {i2=9223372036854775806, i1=2} {i1+i2} 9.22337203685478e+18 + test_expr expr-1.207\ + {i2=9223372036854775806, i1=100000} {i1+i2} 9.22337203685488e+18 + test_expr expr-1.208\ + {i2=9223372036854775807, i1=0} {i1+i2} 9223372036854775807 + test_expr expr-1.209\ + {i2=9223372036854775807, i1=1} {i1+i2} 9.22337203685478e+18 + test_expr expr-1.210\ + {i1=-9223372036854775807, i2=-1} {i1+i2} -9223372036854775808 + test_expr expr-1.211\ + {i1=-9223372036854775807, i2=-2} {i1+i2} -9.22337203685478e+18 + test_expr expr-1.212\ + {i1=-9223372036854775807, i2=-100000} {i1+i2} -9.22337203685488e+18 + test_expr expr-1.213\ + {i1=-9223372036854775808, i2=0} {i1+i2} -9223372036854775808 + test_expr expr-1.214\ + {i1=-9223372036854775808, i2=-1} {i1+i2} -9.22337203685478e+18 + test_expr expr-1.215\ + {i2=-9223372036854775807, i1=-1} {i1+i2} -9223372036854775808 + test_expr expr-1.216\ + {i2=-9223372036854775807, i1=-2} {i1+i2} -9.22337203685478e+18 + test_expr expr-1.217\ + {i2=-9223372036854775807, i1=-100000} {i1+i2} -9.22337203685488e+18 + test_expr expr-1.218\ + {i2=-9223372036854775808, i1=0} {i1+i2} -9223372036854775808 + test_expr expr-1.219\ + {i2=-9223372036854775808, i1=-1} {i1+i2} -9.22337203685478e+18 + test_expr expr-1.220\ + {i1=9223372036854775806, i2=-1} {i1-i2} 9223372036854775807 + test_expr expr-1.221\ + {i1=9223372036854775806, i2=-2} {i1-i2} 9.22337203685478e+18 + test_expr expr-1.222\ + {i1=9223372036854775806, i2=-100000} {i1-i2} 9.22337203685488e+18 + test_expr expr-1.223\ + {i1=9223372036854775807, i2=0} {i1-i2} 9223372036854775807 + test_expr expr-1.224\ + {i1=9223372036854775807, i2=-1} {i1-i2} 9.22337203685478e+18 + test_expr expr-1.225\ + {i2=-9223372036854775806, i1=1} {i1-i2} 9223372036854775807 + test_expr expr-1.226\ + {i2=-9223372036854775806, i1=2} {i1-i2} 9.22337203685478e+18 + test_expr expr-1.227\ + {i2=-9223372036854775806, i1=100000} {i1-i2} 9.22337203685488e+18 + test_expr expr-1.228\ + {i2=-9223372036854775807, i1=0} {i1-i2} 9223372036854775807 + test_expr expr-1.229\ + {i2=-9223372036854775807, i1=1} {i1-i2} 9.22337203685478e+18 + test_expr expr-1.230\ + {i1=-9223372036854775807, i2=1} {i1-i2} -9223372036854775808 + test_expr expr-1.231\ + {i1=-9223372036854775807, i2=2} {i1-i2} -9.22337203685478e+18 + test_expr expr-1.232\ + {i1=-9223372036854775807, i2=100000} {i1-i2} -9.22337203685488e+18 + test_expr expr-1.233\ + {i1=-9223372036854775808, i2=0} {i1-i2} -9223372036854775808 + test_expr expr-1.234\ + {i1=-9223372036854775808, i2=1} {i1-i2} -9.22337203685478e+18 + test_expr expr-1.235\ + {i2=9223372036854775807, i1=-1} {i1-i2} -9223372036854775808 + test_expr expr-1.236\ + {i2=9223372036854775807, i1=-2} {i1-i2} -9.22337203685478e+18 + test_expr expr-1.237\ + {i2=9223372036854775807, i1=-100000} {i1-i2} -9.22337203685488e+18 + test_expr expr-1.238\ + {i2=9223372036854775807, i1=0} {i1-i2} -9223372036854775807 + test_expr expr-1.239\ + {i2=9223372036854775807, i1=-1} {i1-i2} -9223372036854775808 + + test_expr expr-1.250\ + {i1=4294967296, i2=2147483648} {i1*i2} 9.22337203685478e+18 + test_expr expr-1.251\ + {i1=4294967296, i2=2147483647} {i1*i2} 9223372032559808512 + test_expr expr-1.252\ + {i1=-4294967296, i2=2147483648} {i1*i2} -9223372036854775808 + test_expr expr-1.253\ + {i1=-4294967296, i2=2147483647} {i1*i2} -9223372032559808512 + test_expr expr-1.254\ + {i1=4294967296, i2=-2147483648} {i1*i2} -9223372036854775808 + test_expr expr-1.255\ + {i1=4294967296, i2=-2147483647} {i1*i2} -9223372032559808512 + test_expr expr-1.256\ + {i1=-4294967296, i2=-2147483648} {i1*i2} 9.22337203685478e+18 + test_expr expr-1.257\ + {i1=-4294967296, i2=-2147483647} {i1*i2} 9223372032559808512 + +}} + ifcapable floatingpoint { test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 From d7255a207eab440617f4603b016350f075a9bf8b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 5 Mar 2011 21:41:34 +0000 Subject: [PATCH 11/35] Simplifications to the overflow-free multiplier. Also remove some commented-out code that was left in that subroutine by mistake on the previous check-in. FossilOrigin-Name: 55fc25fdab61e6094289e068c343e012fec10439 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/util.c | 6 ++---- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index c596f893ae..de72b49b02 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\sall\sknown\sinstances\sof\ssigned-integer\soverflow.\s\sWithin\sSQL\sexpressions,\ninteger\soverflow\snow\sforces\scoercion\sto\sfloating\spoint.\s\sThe\sshift\soperators\nwork\swith\sany\sinteger\sright-hand\soperand\swith\snegative\svalues\sreversing\nthe\sdirection\sof\sthe\sshift. -D 2011-03-05T20:59:46.394 +C Simplifications\sto\sthe\soverflow-free\smultiplier.\s\sAlso\sremove\ssome\scommented-out\ncode\sthat\swas\sleft\sin\sthat\ssubroutine\sby\smistake\son\sthe\sprevious\scheck-in. +D 2011-03-05T21:41:34.187 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -231,7 +231,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c c849a1e77d00a8a28429a22818155dbf9c311fee +F src/util.c 0e04fb389132f3cfbd5ea69a096206da1cbf32de F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c 038e5689e48cd6597158c5dc34f8d40a03a87ad7 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 04abab71ecd52f6070b9f84781a3df3d6dba7722 -R dffbfc883d2df8713fd0ba30b453b561 +P abf21394124a0af46f072793718964cee2ce55d0 +R 24060eb83e7955ab55ced35ef7d2ddfd U drh -Z e566f37c8f9e6003556e493773a7db62 +Z f1d3fbfcdf98a3d3e54748471aba836e -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNcqRGoxKgR168RlERAlK6AJ9gnf6EDR2ZKhaKkoiA1Nkl5MKeDgCeOJxY -dz92w6QJZQImuyiplDh238s= -=sTB2 +iD8DBQFNcq4RoxKgR168RlERAmdSAJ9o51MyoK1fC2ug7/Csp3X3zbAPjQCfdi/3 +uxlCQmct6yZ8VJBAl19dNj8= +=owHF -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 6a05b41f73..348b2e8a6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abf21394124a0af46f072793718964cee2ce55d0 \ No newline at end of file +55fc25fdab61e6094289e068c343e012fec10439 \ No newline at end of file diff --git a/src/util.c b/src/util.c index b2787974c1..b070bd6ae7 100644 --- a/src/util.c +++ b/src/util.c @@ -1121,15 +1121,13 @@ int sqlite3MulInt64(i64 *pA, i64 iB){ i64 iA = *pA; i64 iA1, iA0, iB1, iB0, r; -// if( iB==1 ){ return 0; } -// if( iA==1 ){ *pA = iB; return 0; } iA1 = iA/TWOPOWER32; iA0 = iA % TWOPOWER32; iB1 = iB/TWOPOWER32; iB0 = iB % TWOPOWER32; if( iA1*iB1 != 0 ) return 1; - r = iA1*iB0; - if( sqlite3AddInt64(&r, iA0*iB1) ) return 1; + assert( iA1*iB0==0 || iA0*iB1==0 ); + r = iA1*iB0 + iA0*iB1; testcase( r==(-TWOPOWER31)-1 ); testcase( r==(-TWOPOWER31) ); testcase( r==TWOPOWER31 ); From c126e63e4fda95f47ffe1cb294b5417c7a46c223 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 6 Mar 2011 21:28:32 +0000 Subject: [PATCH 12/35] Remove dead code identified by the clang static analyzer. FossilOrigin-Name: 01a79d5a7af48fb7e50291c0c7c6283d3fb359d0 --- manifest | 36 ++++++++++++++++++------------------ manifest.uuid | 2 +- src/btree.c | 2 -- src/fkey.c | 2 -- src/insert.c | 4 +--- src/prepare.c | 2 +- src/trigger.c | 1 - src/update.c | 2 -- src/vdbe.c | 2 -- src/vdbeapi.c | 2 -- src/wal.c | 1 - src/where.c | 6 ------ 12 files changed, 21 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index de72b49b02..6030f4be7d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Simplifications\sto\sthe\soverflow-free\smultiplier.\s\sAlso\sremove\ssome\scommented-out\ncode\sthat\swas\sleft\sin\sthat\ssubroutine\sby\smistake\son\sthe\sprevious\scheck-in. -D 2011-03-05T21:41:34.187 +C Remove\sdead\scode\sidentified\sby\sthe\sclang\sstatic\sanalyzer. +D 2011-03-06T21:28:32.373 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -124,7 +124,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 6728d6d48d55b449af76a3e51c0808849cb32a2e F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff -F src/btree.c ca9f44866554f634c12806635bc5b063d70bca9b +F src/btree.c 33265f923a6bcbc035a0914699ab312b93584791 F src/btree.h e2f2cd9933bf30724f53ffa12c4c5a3a864bbd6e F src/btreeInt.h 20f73dc93b1eeb83afd7259fbc6bd7dcf2df7fe4 F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d @@ -135,13 +135,13 @@ F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd F src/expr.c 66c9383e5e1f5259c43ef3aa7883da66cfc0f492 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a +F src/fkey.c 418b840007c873975fd0d071746d952f8bca20ce F src/func.c 3a8cb2fb2de3e3aed7f39106daf4878d9d17fcce F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c a4995747c062256582a90b4f87f716e11b067050 +F src/insert.c 036cfac4be398db9dccdf3200a45e3a7260fcfb2 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -174,7 +174,7 @@ F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1 -F src/prepare.c 395b3fab1b93f45b6aa194b23ebc201221c47b99 +F src/prepare.c 319b47280b6281e6d4f6c57a1651e4f1ea3dac8a F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 @@ -228,24 +228,24 @@ F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 -F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 -F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91 +F src/trigger.c 95d2ff4b2996fabe886c9764b5978980e29f4afa +F src/update.c 81911be16ece3c3e7716aa18565b4814ec41f8b9 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c 0e04fb389132f3cfbd5ea69a096206da1cbf32de F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 038e5689e48cd6597158c5dc34f8d40a03a87ad7 +F src/vdbe.c ac6e8b8264dcc0e4beea44307ff63b1275a9ca3e F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0 -F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d +F src/vdbeapi.c a09ad9164cafc505250d5dd6b69660c960f1308c F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c d8f713bcc3e176040d3e2bb4fbffc3b31faa4252 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 -F src/wal.c 5386fb5e13c2daa8ab9062597fdc17bd849da371 +F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c d7b073867e7bab0b851c659ad4899ce72cc9b81d +F src/where.c 3bc364eeff8625a8438f2bf3a6288c721c9ae475 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125 @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P abf21394124a0af46f072793718964cee2ce55d0 -R 24060eb83e7955ab55ced35ef7d2ddfd +P 55fc25fdab61e6094289e068c343e012fec10439 +R 12067f25ef6d42b31ec1713c62b3af5b U drh -Z f1d3fbfcdf98a3d3e54748471aba836e +Z f391775b0fd982b73d9e78e75989978c -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNcq4RoxKgR168RlERAmdSAJ9o51MyoK1fC2ug7/Csp3X3zbAPjQCfdi/3 -uxlCQmct6yZ8VJBAl19dNj8= -=owHF +iD8DBQFNc/yDoxKgR168RlERAl2jAJ4kMYknXNTsPPqeB+kXrqAfSTDEfACdFMXH +LGyAxYgzfXlJh1jt92GH+Uc= +=iKUD -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 348b2e8a6b..c756f106ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55fc25fdab61e6094289e068c343e012fec10439 \ No newline at end of file +01a79d5a7af48fb7e50291c0c7c6283d3fb359d0 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index f5960da381..fa0889adbe 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6179,9 +6179,7 @@ static int balance_nonroot( } } if( minI>i ){ - int t; MemPage *pT; - t = apNew[i]->pgno; pT = apNew[i]; apNew[i] = apNew[minI]; apNew[minI] = pT; diff --git a/src/fkey.c b/src/fkey.c index a385b814ec..653cc1833a 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -687,7 +687,6 @@ void sqlite3FkCheck( int regNew /* New row data is stored here */ ){ sqlite3 *db = pParse->db; /* Database handle */ - Vdbe *v; /* VM to write code to */ FKey *pFKey; /* Used to iterate through FKs */ int iDb; /* Index of database containing pTab */ const char *zDb; /* Name of database containing pTab */ @@ -699,7 +698,6 @@ void sqlite3FkCheck( /* If foreign-keys are disabled, this function is a no-op. */ if( (db->flags&SQLITE_ForeignKeys)==0 ) return; - v = sqlite3GetVdbe(pParse); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zName; diff --git a/src/insert.c b/src/insert.c index adf6ef2ed4..851f778d48 100644 --- a/src/insert.c +++ b/src/insert.c @@ -465,7 +465,6 @@ void sqlite3Insert( int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ - int regRecord; /* Holds the assemblied row record */ int regEof = 0; /* Register recording end of SELECT data */ int *aRegIdx = 0; /* One register allocated to each index */ @@ -794,7 +793,6 @@ void sqlite3Insert( /* Allocate registers for holding the rowid of the new row, ** the content of the new row, and the assemblied row record. */ - regRecord = ++pParse->nMem; regRowid = regIns = pParse->nMem+1; pParse->nMem += pTab->nCol + 1; if( IsVirtual(pTab) ){ @@ -1188,7 +1186,7 @@ void sqlite3GenerateConstraintChecks( case OE_Rollback: case OE_Fail: { char *zMsg; - j1 = sqlite3VdbeAddOp3(v, OP_HaltIfNull, + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT, onError, regData+i); zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL", pTab->zName, pTab->aCol[i].zName); diff --git a/src/prepare.c b/src/prepare.c index 62a33b6717..d778b8ba9e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -141,7 +141,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int meta[5]; InitData initData; char const *zMasterSchema; - char const *zMasterName = SCHEMA_TABLE(iDb); + char const *zMasterName; int openedTransaction = 0; /* diff --git a/src/trigger.c b/src/trigger.c index b1d43d06d2..ba8d47bccf 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -262,7 +262,6 @@ void sqlite3FinishTrigger( int iDb; /* Database containing the trigger */ Token nameToken; /* Trigger name for error reporting */ - pTrig = pParse->pNewTrigger; pParse->pNewTrigger = 0; if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; zName = pTrig->zName; diff --git a/src/update.c b/src/update.c index 045b4d176d..315034d86f 100644 --- a/src/update.c +++ b/src/update.c @@ -128,7 +128,6 @@ void sqlite3Update( int regNew; int regOld = 0; int regRowSet = 0; /* Rowset of rows to be updated */ - int regRec; /* Register used for new table record to insert */ memset(&sContext, 0, sizeof(sContext)); db = pParse->db; @@ -286,7 +285,6 @@ void sqlite3Update( } regNew = pParse->nMem + 1; pParse->nMem += pTab->nCol; - regRec = ++pParse->nMem; /* Start the view context. */ if( isView ){ diff --git a/src/vdbe.c b/src/vdbe.c index 823688e797..828baa5292 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2429,7 +2429,6 @@ case OP_MakeRecord: { */ nData = 0; /* Number of bytes of data space */ nHdr = 0; /* Number of bytes of header space */ - nByte = 0; /* Data space required for this record */ nZero = 0; /* Number of zero bytes at the end of the record */ nField = pOp->p1; zAffinity = pOp->p4.z; @@ -3703,7 +3702,6 @@ case OP_NewRowid: { /* out2-prerelease */ ** and try again, up to 100 times. */ assert( pC->isTable ); - cnt = 0; #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 5578b868e1..76cd9215a6 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -682,13 +682,11 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){ */ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ Vdbe *pVm; - int vals; Mem *pOut; pVm = (Vdbe *)pStmt; if( pVm && pVm->pResultSet!=0 && inResColumn && i>=0 ){ sqlite3_mutex_enter(pVm->db->mutex); - vals = sqlite3_data_count(pStmt); pOut = &pVm->pResultSet[i]; }else{ /* If the value passed as the second argument is out of range, return diff --git a/src/wal.c b/src/wal.c index 9f7545b61f..51ea18fb21 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1649,7 +1649,6 @@ static int walCheckpoint( } assert( pIter ); - mxPage = pWal->hdr.nPage; if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall; /* Compute in mxSafeFrame the index of the last frame of the WAL that is diff --git a/src/where.c b/src/where.c index 727abdf3f6..72529dde86 100644 --- a/src/where.c +++ b/src/where.c @@ -4047,7 +4047,6 @@ static Bitmask codeOneLoopStart( ** */ WhereClause *pOrWc; /* The OR-clause broken out into subterms */ - WhereTerm *pFinal; /* Final subterm within the OR-clause. */ SrcList *pOrTab; /* Shortened table list or OR-clause generation */ int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ @@ -4063,7 +4062,6 @@ static Bitmask codeOneLoopStart( assert( pTerm->eOperator==WO_OR ); assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); pOrWc = &pTerm->u.pOrInfo->wc; - pFinal = &pOrWc->a[pOrWc->nTerm-1]; pLevel->op = OP_Return; pLevel->p1 = regReturn; @@ -4172,7 +4170,6 @@ static Bitmask codeOneLoopStart( ** the use of indices become tests that are evaluated against each row of ** the relevant input tables. */ - k = 0; for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ Expr *pE; testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ @@ -4190,7 +4187,6 @@ static Bitmask codeOneLoopStart( continue; } sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); - k = 1; pTerm->wtFlags |= TERM_CODED; } @@ -4498,8 +4494,6 @@ WhereInfo *sqlite3WhereBegin( ** clause. */ notReady = ~(Bitmask)0; - pTabItem = pTabList->a; - pLevel = pWInfo->a; andFlags = ~0; WHERETRACE(("*** Optimizer Start ***\n")); for(i=iFrom=0, pLevel=pWInfo->a; i Date: Sun, 6 Mar 2011 21:54:33 +0000 Subject: [PATCH 13/35] Another minor simplification brought to light by clang. FossilOrigin-Name: 3bfbf026dd6a0eeef07f8f5f1ebf74c9cfebcd61 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6030f4be7d..00e7080f20 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Remove\sdead\scode\sidentified\sby\sthe\sclang\sstatic\sanalyzer. -D 2011-03-06T21:28:32.373 +C Another\sminor\ssimplification\sbrought\sto\slight\sby\sclang. +D 2011-03-06T21:54:33.572 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -237,7 +237,7 @@ F src/vdbe.c ac6e8b8264dcc0e4beea44307ff63b1275a9ca3e F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0 F src/vdbeapi.c a09ad9164cafc505250d5dd6b69660c960f1308c -F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af +F src/vdbeaux.c 00439455c80ff7b37d7f2e5be5c0cf02de732a42 F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c d8f713bcc3e176040d3e2bb4fbffc3b31faa4252 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 55fc25fdab61e6094289e068c343e012fec10439 -R 12067f25ef6d42b31ec1713c62b3af5b +P 01a79d5a7af48fb7e50291c0c7c6283d3fb359d0 +R f26f22d38e31d99ab2a9418e84c97bed U drh -Z f391775b0fd982b73d9e78e75989978c +Z a115c36c7eaf4f6e951cb7f5d4e94ec0 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNc/yDoxKgR168RlERAl2jAJ4kMYknXNTsPPqeB+kXrqAfSTDEfACdFMXH -LGyAxYgzfXlJh1jt92GH+Uc= -=iKUD +iD8DBQFNdAKcoxKgR168RlERAtyUAJ9ywxjzGGZVVqunZ3Nt1qv9pd2YmgCfR7rm +kZxrrIHa7TLJ4O/kbYiB2Mw= +=Rm5M -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index c756f106ac..3ee000c911 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01a79d5a7af48fb7e50291c0c7c6283d3fb359d0 \ No newline at end of file +3bfbf026dd6a0eeef07f8f5f1ebf74c9cfebcd61 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4a1b1efbb2..c7acbcb646 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1517,7 +1517,7 @@ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ */ static void closeAllCursors(Vdbe *p){ if( p->pFrame ){ - VdbeFrame *pFrame = p->pFrame; + VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); sqlite3VdbeFrameRestore(pFrame); } From d50ffc416fc47ad9ed6c643d4aaba0df2e59254c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Mar 2011 02:38:28 +0000 Subject: [PATCH 14/35] Fix additional cases of possible signed integer overflow, especially with regard to negation. FossilOrigin-Name: 2d5800bd8cfc7d7f5578a71b1aeaa74b2ec4b372 --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/btree.c | 6 ++---- src/expr.c | 11 ++++------- src/pragma.c | 6 ++---- src/prepare.c | 3 +-- src/sqliteInt.h | 3 ++- src/util.c | 10 ++++++++++ src/vdbemem.c | 11 ++++++++--- 9 files changed, 45 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 00e7080f20..61ec936a43 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Another\sminor\ssimplification\sbrought\sto\slight\sby\sclang. -D 2011-03-06T21:54:33.572 +C Fix\sadditional\scases\sof\spossible\ssigned\sinteger\soverflow,\sespecially\swith\nregard\sto\snegation. +D 2011-03-08T02:38:28.410 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -124,7 +124,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 6728d6d48d55b449af76a3e51c0808849cb32a2e F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff -F src/btree.c 33265f923a6bcbc035a0914699ab312b93584791 +F src/btree.c 43302cc4f3de6479b90fa6bb271b65d86333d00e F src/btree.h e2f2cd9933bf30724f53ffa12c4c5a3a864bbd6e F src/btreeInt.h 20f73dc93b1eeb83afd7259fbc6bd7dcf2df7fe4 F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d @@ -133,7 +133,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd -F src/expr.c 66c9383e5e1f5259c43ef3aa7883da66cfc0f492 +F src/expr.c 00817c672af554321fd67c44325afd7cef0e4648 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 418b840007c873975fd0d071746d952f8bca20ce F src/func.c 3a8cb2fb2de3e3aed7f39106daf4878d9d17fcce @@ -173,8 +173,8 @@ F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e -F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1 -F src/prepare.c 319b47280b6281e6d4f6c57a1651e4f1ea3dac8a +F src/pragma.c 4221eb822d7cdb1fb69be555b189e15e5a24b6b5 +F src/prepare.c eb4944d9f7bfa13eb42a7416ed9aaed4de4d0bf3 F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 @@ -183,7 +183,7 @@ F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 118481da7db00c4ae2709ed8af6498be900e6ae0 +F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -231,7 +231,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c 95d2ff4b2996fabe886c9764b5978980e29f4afa F src/update.c 81911be16ece3c3e7716aa18565b4814ec41f8b9 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c 0e04fb389132f3cfbd5ea69a096206da1cbf32de +F src/util.c f6c87805d36799a0d90ea6f0c8c961bee84a6950 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c ac6e8b8264dcc0e4beea44307ff63b1275a9ca3e F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 @@ -239,7 +239,7 @@ F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0 F src/vdbeapi.c a09ad9164cafc505250d5dd6b69660c960f1308c F src/vdbeaux.c 00439455c80ff7b37d7f2e5be5c0cf02de732a42 F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c -F src/vdbemem.c d8f713bcc3e176040d3e2bb4fbffc3b31faa4252 +F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 01a79d5a7af48fb7e50291c0c7c6283d3fb359d0 -R f26f22d38e31d99ab2a9418e84c97bed +P 3bfbf026dd6a0eeef07f8f5f1ebf74c9cfebcd61 +R 14384a8f4890b1a5943c537e15c8a789 U drh -Z a115c36c7eaf4f6e951cb7f5d4e94ec0 +Z f625fb04060bd1f53406bce59c01aeac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNdAKcoxKgR168RlERAtyUAJ9ywxjzGGZVVqunZ3Nt1qv9pd2YmgCfR7rm -kZxrrIHa7TLJ4O/kbYiB2Mw= -=Rm5M +iD8DBQFNdZanoxKgR168RlERAuRYAJ9wNMACH3kVtSPlH9ioTxMSTFcVAwCdEtGo +QSf9S56IOhmO4JkP2her+Ik= +=G+By -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 3ee000c911..5beb948d1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bfbf026dd6a0eeef07f8f5f1ebf74c9cfebcd61 \ No newline at end of file +2d5800bd8cfc7d7f5578a71b1aeaa74b2ec4b372 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index fa0889adbe..33d7460675 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4901,11 +4901,9 @@ static int allocateBtreePage( u32 i; int dist; closest = 0; - dist = get4byte(&aData[8]) - nearby; - if( dist<0 ) dist = -dist; + dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby); for(i=1; iz==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ nExtra = pToken->n+1; + assert( iValue>=0 ); } } pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra); @@ -614,6 +615,8 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ */ void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p==0 ) return; + /* Sanity check: Assert that the IntValue is non-negative if it exists */ + assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ sqlite3ExprDelete(db, p->pLeft); sqlite3ExprDelete(db, p->pRight); @@ -1223,13 +1226,6 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){ } default: break; } - if( rc ){ - assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly) - || (p->flags2 & EP2_MallocedToken)==0 ); - p->op = TK_INTEGER; - p->flags |= EP_IntValue; - p->u.iValue = *pValue; - } return rc; } @@ -1954,6 +1950,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ Vdbe *v = pParse->pVdbe; if( pExpr->flags & EP_IntValue ){ int i = pExpr->u.iValue; + assert( i>=0 ); if( negFlag ) i = -i; sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); }else{ diff --git a/src/pragma.c b/src/pragma.c index cbfe01f014..db55e4bb41 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -384,8 +384,7 @@ void sqlite3Pragma( sqlite3VdbeChangeP1(v, addr+1, iDb); sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); }else{ - int size = sqlite3Atoi(zRight); - if( size<0 ) size = -size; + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, size, 1); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); @@ -694,8 +693,7 @@ void sqlite3Pragma( if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ - int size = sqlite3Atoi(zRight); - if( size<0 ) size = -size; + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } diff --git a/src/prepare.c b/src/prepare.c index d778b8ba9e..45654ecfca 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -278,9 +278,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ pDb->pSchema->enc = ENC(db); if( pDb->pSchema->cache_size==0 ){ - size = meta[BTREE_DEFAULT_CACHE_SIZE-1]; + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } - if( size<0 ) size = -size; pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bbf1b16883..0142d1e9d3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1623,7 +1623,7 @@ struct Expr { u16 flags; /* Various flags. EP_* See below */ union { char *zToken; /* Token value. Zero terminated and dequoted */ - int iValue; /* Integer value if EP_IntValue */ + int iValue; /* Non-negative integer value if EP_IntValue */ } u; /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no @@ -2906,6 +2906,7 @@ void sqlite3VdbeSetChanges(sqlite3 *, int); int sqlite3AddInt64(i64*,i64); int sqlite3SubInt64(i64*,i64); int sqlite3MulInt64(i64*,i64); +int sqlite3AbsInt32(int); const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8); diff --git a/src/util.c b/src/util.c index b070bd6ae7..05934c4602 100644 --- a/src/util.c +++ b/src/util.c @@ -1138,3 +1138,13 @@ int sqlite3MulInt64(i64 *pA, i64 iB){ *pA = r; return 0; } + +/* +** Compute the absolute value of a 32-bit signed integer, of possible. Or +** if the integer has a value of -2147483648, return +2147483647 +*/ +int sqlite3AbsInt32(int x){ + if( x>=0 ) return x; + if( x==0x80000000 ) return 0x7fffffff; + return -x; +} diff --git a/src/vdbemem.c b/src/vdbemem.c index d2fdeb7ee9..882c686334 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1077,9 +1077,14 @@ int sqlite3ValueFromExpr( /* This branch happens for multiple negative signs. Ex: -(-5) */ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ sqlite3VdbeMemNumerify(pVal); - pVal->u.i = -1 * pVal->u.i; - /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */ - pVal->r = (double)-1 * pVal->r; + if( pVal->u.i==SMALLEST_INT64 ){ + pVal->flags &= MEM_Int; + pVal->flags |= MEM_Real; + pVal->r = (double)LARGEST_INT64; + }else{ + pVal->u.i = -pVal->u.i; + } + pVal->r = -pVal->r; sqlite3ValueApplyAffinity(pVal, affinity, enc); } }else if( op==TK_NULL ){ From 87e79aefefb800a9789bded1c31cd9ec0d90c187 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Mar 2011 13:06:41 +0000 Subject: [PATCH 15/35] Fix two compiler warnings. No functional code changes. FossilOrigin-Name: c829868aa2254c5e2268cdb803462cc6ec5cb71e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os_unix.c | 1 + src/util.c | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 61ec936a43..2f857e15db 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\sadditional\scases\sof\spossible\ssigned\sinteger\soverflow,\sespecially\swith\nregard\sto\snegation. -D 2011-03-08T02:38:28.410 +C Fix\stwo\scompiler\swarnings.\s\sNo\sfunctional\scode\schanges. +D 2011-03-08T13:06:41.560 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 -F src/os_unix.c 54cd8b64e342984cb9a565d8bbd3d4ed4f6679ad +F src/os_unix.c 67f9a304641f126f5f7326cd452c2df3d9a4d512 F src/os_win.c 9abdcdd925416d854eabb0996c96debd92abfef5 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -231,7 +231,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c 95d2ff4b2996fabe886c9764b5978980e29f4afa F src/update.c 81911be16ece3c3e7716aa18565b4814ec41f8b9 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c f6c87805d36799a0d90ea6f0c8c961bee84a6950 +F src/util.c cd997077bad039efc0597eb027c929658f93c018 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c ac6e8b8264dcc0e4beea44307ff63b1275a9ca3e F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3bfbf026dd6a0eeef07f8f5f1ebf74c9cfebcd61 -R 14384a8f4890b1a5943c537e15c8a789 +P 2d5800bd8cfc7d7f5578a71b1aeaa74b2ec4b372 +R 041c7b161bddb56919915095c6eecb0a U drh -Z f625fb04060bd1f53406bce59c01aeac +Z 4d3f158d515c892cb9d8cf0046e71654 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNdZanoxKgR168RlERAuRYAJ9wNMACH3kVtSPlH9ioTxMSTFcVAwCdEtGo -QSf9S56IOhmO4JkP2her+Ik= -=G+By +iD8DBQFNdinkoxKgR168RlERAjW4AJ0VMtFmIHefKTsESvaC3Qf84rP9gwCdHHsc +QH4FUHE8AWOo5yx+Cxq1TMw= +=jciZ -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 5beb948d1c..f483a27486 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d5800bd8cfc7d7f5578a71b1aeaa74b2ec4b372 \ No newline at end of file +c829868aa2254c5e2268cdb803462cc6ec5cb71e \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 40e4b89cd6..b2374beec3 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1357,6 +1357,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( eFileLock==SHARED_LOCK ){ #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE + (void)handleNFSUnlock; assert( handleNFSUnlock==0 ); #endif #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE diff --git a/src/util.c b/src/util.c index 05934c4602..5cc2b61308 100644 --- a/src/util.c +++ b/src/util.c @@ -1145,6 +1145,6 @@ int sqlite3MulInt64(i64 *pA, i64 iB){ */ int sqlite3AbsInt32(int x){ if( x>=0 ) return x; - if( x==0x80000000 ) return 0x7fffffff; + if( x==(int)0x80000000 ) return 0x7fffffff; return -x; } From 66d655b40945664c59a0c6bfd269724a75927559 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Mar 2011 14:05:07 +0000 Subject: [PATCH 16/35] Unix errno integer can vary from one system to the next. So do not depend on specific errno values in test cases. FossilOrigin-Name: ddb747d33a004c7fe532a661e879ccba68c79c59 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- test/oserror.test | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 2f857e15db..5e56fbba6c 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\stwo\scompiler\swarnings.\s\sNo\sfunctional\scode\schanges. -D 2011-03-08T13:06:41.560 +C Unix\serrno\sinteger\scan\svary\sfrom\sone\ssystem\sto\sthe\snext.\s\sSo\sdo\snot\ndepend\son\sspecific\serrno\svalues\sin\stest\scases. +D 2011-03-08T14:05:07.476 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -587,7 +587,7 @@ F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec -F test/oserror.test 8fc832600afe2b983f2347bfb3cbb88a80aeb347 +F test/oserror.test d1f085bdbac20456fccdf5877f52016453654fc3 F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2d5800bd8cfc7d7f5578a71b1aeaa74b2ec4b372 -R 041c7b161bddb56919915095c6eecb0a +P c829868aa2254c5e2268cdb803462cc6ec5cb71e +R 8e95dcc047fadda9627799dfff537929 U drh -Z 4d3f158d515c892cb9d8cf0046e71654 +Z 37a2076ebac96d581357fbed13c5025e -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNdinkoxKgR168RlERAjW4AJ0VMtFmIHefKTsESvaC3Qf84rP9gwCdHHsc -QH4FUHE8AWOo5yx+Cxq1TMw= -=jciZ +iD8DBQFNdjeWoxKgR168RlERAqe0AJ0VGxcf5Ph+FO32DM9O7OJzqJKoKgCgi6Pc +n0W6zXncDy5KyrZP5XyTfdc= +=lDvF -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index f483a27486..2cb1327c66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c829868aa2254c5e2268cdb803462cc6ec5cb71e \ No newline at end of file +ddb747d33a004c7fe532a661e879ccba68c79c59 \ No newline at end of file diff --git a/test/oserror.test b/test/oserror.test index e44a674192..ecb02116ba 100644 --- a/test/oserror.test +++ b/test/oserror.test @@ -56,7 +56,7 @@ do_test 1.1.2 { catch { for {set i 0} {$i < 2000} {incr i} { dbh_$i close } } } {1} -do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c:\d*: \(24\) open\(.*test.db\) - } +do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*test.db\) - } # Test a failure in open() due to the path being a directory. @@ -67,7 +67,7 @@ do_test 1.2.1 { list [catch { sqlite3 dbh dir.db } msg] $msg } {1 {unable to open database file}} -do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c:\d*: \(21\) open\(.*dir.db\) - } +do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*dir.db\) - } # Test a failure in open() due to the path not existing. # @@ -76,7 +76,7 @@ do_test 1.3.1 { list [catch { sqlite3 dbh /x/y/z/test.db } msg] $msg } {1 {unable to open database file}} -do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c:\d*: \(2\) open\(.*test.db\) - } +do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*test.db\) - } # Test a failure in open() due to the path not existing. # @@ -85,7 +85,7 @@ do_test 1.4.1 { list [catch { sqlite3 dbh /root/test.db } msg] $msg } {1 {unable to open database file}} -do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(13\) open\(.*test.db\) - } +do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(\d+\) open\(.*test.db\) - } #-------------------------------------------------------------------------- # Tests oserror-1.* test failures in the unlink() system call. @@ -98,7 +98,7 @@ do_test 2.1.1 { catchsql { SELECT * FROM sqlite_master } dbh } {1 {disk I/O error}} -do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c:\d*: \(21\) unlink\(.*test.db-wal\) - } +do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) unlink\(.*test.db-wal\) - } do_test 2.1.3 { dbh close forcedelete test.db-wal From a1df4bfc1ac73de0ca36e36da52d22b7c291586f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Mar 2011 11:04:07 +0000 Subject: [PATCH 17/35] Updates to the OS/2 implementation from Rich Walsh. FossilOrigin-Name: dc46156a2237701679433779b871844f4f2abe4b --- manifest | 20 ++--- manifest.uuid | 2 +- src/mutex_os2.c | 125 ++++++++++++++-------------- src/os_os2.c | 217 +++++++++++++++++++++++++++++++----------------- 4 files changed, 216 insertions(+), 148 deletions(-) diff --git a/manifest b/manifest index d1be39e105..87bc1de9eb 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Merge\sthe\ssyscall-override\schanges\sinto\strunk. -D 2011-03-08T16:39:29.275 +C Updates\sto\sthe\sOS/2\simplementation\sfrom\sRich\sWalsh. +D 2011-03-09T11:04:07.809 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,14 +157,14 @@ F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6 F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151 -F src/mutex_os2.c 6a62583e374ba3ac1a3fcc0da2bfdac7d3942689 +F src/mutex_os2.c f5d09e85b914643c230aa97db709fc0db370d93c F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_w32.c 3ade5ae71449d1d023f0ebb3184c2ae6aa9307e4 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f -F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863 +F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf F src/os_unix.c 58fe8845678f6a4e30ed6988c5df7327bc7bd69b F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ddb747d33a004c7fe532a661e879ccba68c79c59 a7d176b27cd73791d45eb3a31df78187ae10ce20 -R f6d9df8153eea975bd4c019ada4938a6 +P 36d79e6f54cdc4129c6e6366a49722e2cf1cccbd +R 2f4313abc92b495e5c25d9ed87ce7d46 U drh -Z a4115902c8e36dff16feb9c6102d7895 +Z fe519f199afd232fa32e880111460489 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNdlvEoxKgR168RlERAqctAJ0QkDzaXcGb8cYDn6Z1juSfygSdZgCcCoJg -HYxK6HQIevTUFNLB5q3ux8E= -=p3yO +iD8DBQFNd16roxKgR168RlERAjIHAJsFi1zIg+NnkZ8ozYY79qgeXOHlWwCcDItu +3AD87d08lqXy+gxk5jGCRwA= +=eyUa -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index feb46f5c92..9c1d0bbe23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36d79e6f54cdc4129c6e6366a49722e2cf1cccbd \ No newline at end of file +dc46156a2237701679433779b871844f4f2abe4b \ No newline at end of file diff --git a/src/mutex_os2.c b/src/mutex_os2.c index 4438c097c4..85129f3e48 100644 --- a/src/mutex_os2.c +++ b/src/mutex_os2.c @@ -31,11 +31,16 @@ struct sqlite3_mutex { HMTX mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ - int nRef; /* Number of references */ - TID owner; /* Thread holding this mutex */ +#ifdef SQLITE_DEBUG + int trace; /* True to trace changes */ +#endif }; -#define OS2_MUTEX_INITIALIZER 0,0,0,0 +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { 0, 0 } +#endif /* ** Initialize and deinitialize the mutex subsystem. @@ -51,11 +56,14 @@ static int os2MutexEnd(void){ return SQLITE_OK; } ** to sqlite3_mutex_alloc() is one of these integer constants: ** **
    -**
  • SQLITE_MUTEX_FAST 0 -**
  • SQLITE_MUTEX_RECURSIVE 1 -**
  • SQLITE_MUTEX_STATIC_MASTER 2 -**
  • SQLITE_MUTEX_STATIC_MEM 3 -**
  • SQLITE_MUTEX_STATIC_PRNG 4 +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 **
** ** The first two constants cause sqlite3_mutex_alloc() to create @@ -69,7 +77,7 @@ static int os2MutexEnd(void){ return SQLITE_OK; } ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Three static mutexes are +** a pointer to a static preexisting mutex. Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -99,13 +107,13 @@ static sqlite3_mutex *os2MutexAlloc(int iType){ } default: { static volatile int isInit = 0; - static sqlite3_mutex staticMutexes[] = { - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, - { OS2_MUTEX_INITIALIZER, }, + static sqlite3_mutex staticMutexes[6] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, }; if ( !isInit ){ APIRET rc; @@ -151,9 +159,14 @@ static sqlite3_mutex *os2MutexAlloc(int iType){ ** SQLite is careful to deallocate every mutex that it allocates. */ static void os2MutexFree(sqlite3_mutex *p){ - if( p==0 ) return; - assert( p->nRef==0 ); +#ifdef SQLITE_DEBUG + TID tid; + PID pid; + ULONG ulCount; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + assert( ulCount==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif DosCloseMutexSem( p->mutex ); sqlite3_free( p ); } @@ -168,26 +181,29 @@ static int os2MutexHeld(sqlite3_mutex *p){ PID pid; ULONG ulCount; PTIB ptib; - if( p!=0 ) { - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - } else { - DosGetInfoBlocks(&ptib, NULL); - tid = ptib->tib_ptib2->tib2_ultid; - } - return p==0 || (p->nRef!=0 && p->owner==tid); + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) ) + return 0; + DosGetInfoBlocks(&ptib, NULL); + return tid==ptib->tib_ptib2->tib2_ultid; } static int os2MutexNotheld(sqlite3_mutex *p){ TID tid; PID pid; ULONG ulCount; PTIB ptib; - if( p!= 0 ) { - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); - } else { - DosGetInfoBlocks(&ptib, NULL); - tid = ptib->tib_ptib2->tib2_ultid; - } - return p==0 || p->nRef==0 || p->owner!=tid; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + if( ulCount==0 ) + return 1; + DosGetInfoBlocks(&ptib, NULL); + return tid!=ptib->tib_ptib2->tib2_ultid; +} +static void os2MutexTrace(sqlite3_mutex *p, char *pAction){ + TID tid; + PID pid; + ULONG ulCount; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount); } #endif @@ -203,32 +219,21 @@ static int os2MutexNotheld(sqlite3_mutex *p){ ** more than once, the behavior is undefined. */ static void os2MutexEnter(sqlite3_mutex *p){ - TID tid; - PID holder1; - ULONG holder2; - if( p==0 ) return; assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); - p->owner = tid; - p->nRef++; +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "enter"); +#endif } static int os2MutexTry(sqlite3_mutex *p){ - int rc; - TID tid; - PID holder1; - ULONG holder2; - if( p==0 ) return SQLITE_OK; + int rc = SQLITE_BUSY; assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); - if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) { - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); - p->owner = tid; - p->nRef++; + if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) { rc = SQLITE_OK; - } else { - rc = SQLITE_BUSY; +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "try"); +#endif } - return rc; } @@ -239,19 +244,14 @@ static int os2MutexTry(sqlite3_mutex *p){ ** is not currently allocated. SQLite will never do either. */ static void os2MutexLeave(sqlite3_mutex *p){ - TID tid; - PID holder1; - ULONG holder2; - if( p==0 ) return; - assert( p->nRef>0 ); - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); - assert( p->owner==tid ); - p->nRef--; - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + assert( os2MutexHeld(p) ); DosReleaseMutexSem(p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "leave"); +#endif } -sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ static const sqlite3_mutex_methods sMutex = { os2MutexInit, os2MutexEnd, @@ -263,6 +263,9 @@ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ #ifdef SQLITE_DEBUG os2MutexHeld, os2MutexNotheld +#else + 0, + 0 #endif }; diff --git a/src/os_os2.c b/src/os_os2.c index df5ad1026b..2a786b4dea 100644 --- a/src/os_os2.c +++ b/src/os_os2.c @@ -646,19 +646,23 @@ char *convertCpPathToUtf8( const char *in ){ ** sqlite3_file for os2. */ static const sqlite3_io_methods os2IoMethod = { - 1, /* iVersion */ - os2Close, - os2Read, - os2Write, - os2Truncate, - os2Sync, - os2FileSize, - os2Lock, - os2Unlock, - os2CheckReservedLock, - os2FileControl, - os2SectorSize, - os2DeviceCharacteristics + 1, /* iVersion */ + os2Close, /* xClose */ + os2Read, /* xRead */ + os2Write, /* xWrite */ + os2Truncate, /* xTruncate */ + os2Sync, /* xSync */ + os2FileSize, /* xFileSize */ + os2Lock, /* xLock */ + os2Unlock, /* xUnlock */ + os2CheckReservedLock, /* xCheckReservedLock */ + os2FileControl, /* xFileControl */ + os2SectorSize, /* xSectorSize */ + os2DeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0 /* xShmUnmap */ }; /*************************************************************************** @@ -750,100 +754,137 @@ static int os2FullPathname( */ static int os2Open( sqlite3_vfs *pVfs, /* Not used */ - const char *zName, /* Name of the file */ + const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ int *pOutFlags /* Status return flags */ ){ HFILE h; - ULONG ulFileAttribute = FILE_NORMAL; ULONG ulOpenFlags = 0; ULONG ulOpenMode = 0; + ULONG ulAction = 0; + ULONG rc; os2File *pFile = (os2File*)id; - APIRET rc = NO_ERROR; - ULONG ulAction; + const char *zUtf8Name = zName; char *zNameCp; - char zTmpname[CCHMAXPATH+1]; /* Buffer to hold name of temp file */ + char zTmpname[CCHMAXPATH]; + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#ifndef NDEBUG + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int eType = (flags & 0xFFFFFF00); + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + UNUSED_PARAMETER(pVfs); + assert( id!=0 ); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + memset( pFile, 0, sizeof(*pFile) ); + pFile->pMethod = &os2IoMethod; /* If the second argument to this function is NULL, generate a ** temporary file name to use */ - if( !zName ){ - int rc = getTempname(CCHMAXPATH+1, zTmpname); + if( !zUtf8Name ){ + assert(isDelete && !isOpenJournal); + rc = getTempname(CCHMAXPATH, zTmpname); if( rc!=SQLITE_OK ){ return rc; } - zName = zTmpname; + zUtf8Name = zTmpname; } - - memset( pFile, 0, sizeof(*pFile) ); - - OSTRACE(( "OPEN want %d\n", flags )); - - if( flags & SQLITE_OPEN_READWRITE ){ + if( isReadWrite ){ ulOpenMode |= OPEN_ACCESS_READWRITE; - OSTRACE(( "OPEN read/write\n" )); }else{ ulOpenMode |= OPEN_ACCESS_READONLY; - OSTRACE(( "OPEN read only\n" )); } - if( flags & SQLITE_OPEN_CREATE ){ - ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; - OSTRACE(( "OPEN open new/create\n" )); - }else{ - ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW; - OSTRACE(( "OPEN open existing\n" )); - } - - if( flags & SQLITE_OPEN_MAIN_DB ){ - ulOpenMode |= OPEN_SHARE_DENYNONE; - OSTRACE(( "OPEN share read/write\n" )); - }else{ - ulOpenMode |= OPEN_SHARE_DENYWRITE; - OSTRACE(( "OPEN share read only\n" )); - } - - if( flags & SQLITE_OPEN_DELETEONCLOSE ){ - char pathUtf8[CCHMAXPATH]; -#ifdef NDEBUG /* when debugging we want to make sure it is deleted */ - ulFileAttribute = FILE_HIDDEN; -#endif - os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 ); - pFile->pathToDel = convertUtf8PathToCp( pathUtf8 ); - OSTRACE(( "OPEN hidden/delete on close file attributes\n" )); - }else{ - pFile->pathToDel = NULL; - OSTRACE(( "OPEN normal file attribute\n" )); - } - - /* always open in random access mode for possibly better speed */ + /* Open in random access mode for possibly better speed. Allow full + ** sharing because file locks will provide exclusive access when needed. + */ ulOpenMode |= OPEN_FLAGS_RANDOM; ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; ulOpenMode |= OPEN_FLAGS_NOINHERIT; + ulOpenMode |= OPEN_SHARE_DENYNONE; - zNameCp = convertUtf8PathToCp( zName ); + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; + }else{ + /* Opens a file, only if it exists. */ + ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; + } + + /* For DELETEONCLOSE, save a pointer to the converted filename */ + if( isDelete ){ + char pathUtf8[CCHMAXPATH]; + os2FullPathname( pVfs, zUtf8Name, CCHMAXPATH, pathUtf8 ); + pFile->pathToDel = convertUtf8PathToCp( pathUtf8 ); + } + + zNameCp = convertUtf8PathToCp( zUtf8Name ); rc = DosOpen( (PSZ)zNameCp, &h, &ulAction, 0L, - ulFileAttribute, + FILE_NORMAL, ulOpenFlags, ulOpenMode, (PEAOP2)NULL ); free( zNameCp ); + if( rc != NO_ERROR ){ - OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", - rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode )); + OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n", + rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode )); if( pFile->pathToDel ) free( pFile->pathToDel ); pFile->pathToDel = NULL; - if( flags & SQLITE_OPEN_READWRITE ){ - OSTRACE(( "OPEN %d Invalid handle\n", - ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) )); + + if( isReadWrite ){ return os2Open( pVfs, zName, id, - ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE), + ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags ); }else{ return SQLITE_CANTOPEN; @@ -851,10 +892,9 @@ static int os2Open( } if( pOutFlags ){ - *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; + *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; } - pFile->pMethod = &os2IoMethod; pFile->h = h; OpenCounter(+1); OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags )); @@ -869,13 +909,16 @@ static int os2Delete( const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on os2 */ ){ - APIRET rc = NO_ERROR; - char *zFilenameCp = convertUtf8PathToCp( zFilename ); + APIRET rc; + char *zFilenameCp; SimulateIOError( return SQLITE_IOERR_DELETE ); + zFilenameCp = convertUtf8PathToCp( zFilename ); rc = DosDelete( (PSZ)zFilenameCp ); free( zFilenameCp ); OSTRACE(( "DELETE \"%s\"\n", zFilename )); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE; + return (rc == NO_ERROR || + rc == ERROR_FILE_NOT_FOUND || + rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE; } /* @@ -940,7 +983,7 @@ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ /* no-op */ } -static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ +static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ PFN pfn; APIRET rc; rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn); @@ -952,7 +995,7 @@ static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ strncat(_zSymbol, zSymbol, 255); rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn); } - return rc != NO_ERROR ? 0 : (void*)pfn; + return rc != NO_ERROR ? 0 : (void(*)(void))pfn; } static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ DosFreeModule((HMODULE)pHandle); @@ -1056,10 +1099,11 @@ int sqlite3_current_time = 0; int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ double now; SHORT minute; /* needs to be able to cope with negative timezone offset */ - USHORT second, hour, + USHORT hundredths, second, hour, day, month, year; DATETIME dt; DosGetDateTime( &dt ); + hundredths = (USHORT)dt.hundredths; second = (USHORT)dt.seconds; minute = (SHORT)dt.minutes + dt.timezone; hour = (USHORT)dt.hours; @@ -1079,6 +1123,7 @@ int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ now += (hour + 12.0)/24.0; now += minute/1440.0; now += second/86400.0; + now += hundredths/8640000.0; *prNow = now; #ifdef SQLITE_TEST if( sqlite3_current_time ){ @@ -1088,6 +1133,22 @@ int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ return 0; } +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return 0. Return 1 if the time and date cannot be found. +*/ +static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ + double now; + os2CurrentTime(pVfs, &now); + *piNow = now * 86400000; + return 0; +} + static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ return 0; } @@ -1097,7 +1158,7 @@ static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ */ int sqlite3_os_init(void){ static sqlite3_vfs os2Vfs = { - 1, /* iVersion */ + 3, /* iVersion */ sizeof(os2File), /* szOsFile */ CCHMAXPATH, /* mxPathname */ 0, /* pNext */ @@ -1116,6 +1177,10 @@ int sqlite3_os_init(void){ os2Sleep, /* xSleep */ os2CurrentTime, /* xCurrentTime */ os2GetLastError, /* xGetLastError */ + os2CurrentTimeInt64 /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0, /* xNextSystemCall */ }; sqlite3_vfs_register(&os2Vfs, 1); initUconvObjects(); From 95e037ba39530c048897d7b08493e2e3336d6961 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Mar 2011 21:02:31 +0000 Subject: [PATCH 18/35] Omit unnecessary OP_Next and OP_Prev operators when uniqueness constraints guarantee that the code will only make one pass through the loop. FossilOrigin-Name: f000c9b2b7348238fe2085140d2dd05294a19709 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/where.c | 8 +++++++- test/index.test | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 87bc1de9eb..6e716ca725 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Updates\sto\sthe\sOS/2\simplementation\sfrom\sRich\sWalsh. -D 2011-03-09T11:04:07.809 +C Omit\sunnecessary\sOP_Next\sand\sOP_Prev\soperators\swhen\suniqueness\sconstraints\nguarantee\sthat\sthe\scode\swill\sonly\smake\sone\spass\sthrough\sthe\sloop. +D 2011-03-09T21:02:31.691 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -245,7 +245,7 @@ F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 3bc364eeff8625a8438f2bf3a6288c721c9ae475 +F src/where.c 27c2f4e249213faeab548f628e52c005623f195d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125 @@ -490,7 +490,7 @@ F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0 F test/incrvacuum.test 453d1e490d8f5ad2c9b3a54282a0690d6ae56462 F test/incrvacuum2.test 9e22a794899c91b7d8c8e12eaacac8df249faafe F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291 -F test/index.test df7c00c6edd9504ab71c83a9514f1c5ca0fa54d8 +F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/indexedby.test be501e381b82b2f8ab406309ba7aac46e221f4ad @@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 36d79e6f54cdc4129c6e6366a49722e2cf1cccbd -R 2f4313abc92b495e5c25d9ed87ce7d46 +P dc46156a2237701679433779b871844f4f2abe4b +R 6a96206125f553ae6e4986479b4fa19e U drh -Z fe519f199afd232fa32e880111460489 +Z 3c4f85bbdfea18f22f89d0b2d92c8936 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNd16roxKgR168RlERAjIHAJsFi1zIg+NnkZ8ozYY79qgeXOHlWwCcDItu -3AD87d08lqXy+gxk5jGCRwA= -=eyUa +iD8DBQFNd+rroxKgR168RlERAk+tAJ9jEIHTwnjObklOR5pMe4sV08k4IgCeI8br +wFEqDe541wz3+xTQUIuHIUY= +=D87j -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 9c1d0bbe23..8d40b7424d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc46156a2237701679433779b871844f4f2abe4b \ No newline at end of file +f000c9b2b7348238fe2085140d2dd05294a19709 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 72529dde86..2b89055251 100644 --- a/src/where.c +++ b/src/where.c @@ -4001,7 +4001,13 @@ static Bitmask codeOneLoopStart( /* Record the instruction used to terminate the loop. Disable ** WHERE clause terms made redundant by the index range scan. */ - pLevel->op = bRev ? OP_Prev : OP_Next; + if( pLevel->plan.wsFlags & WHERE_UNIQUE ){ + pLevel->op = OP_Noop; + }else if( bRev ){ + pLevel->op = OP_Prev; + }else{ + pLevel->op = OP_Next; + } pLevel->p1 = iIdxCur; }else diff --git a/test/index.test b/test/index.test index 0a41a6de3e..790bed908e 100644 --- a/test/index.test +++ b/test/index.test @@ -354,7 +354,7 @@ do_test index-11.1 { } set sqlite_search_count 0 concat [execsql {SELECT c FROM t3 WHERE b==10}] $sqlite_search_count -} {0.1 3} +} {0.1 2} integrity_check index-11.2 From a6ec892b5becd14478f41f617dcc764341e9e59f Mon Sep 17 00:00:00 2001 From: shaneh Date: Wed, 9 Mar 2011 21:36:17 +0000 Subject: [PATCH 19/35] Fix issue with mem5 allocator when min request size is larger thatn 2^30. FossilOrigin-Name: d7dae06fb2d57ed6b9555b774712f42077ae4155 --- manifest | 29 ++++++++-------------- manifest.uuid | 2 +- src/main.c | 7 ++++++ src/mem5.c | 7 ++++-- src/sqlite.h.in | 4 ++- test/mem5.test | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 23 deletions(-) create mode 100644 test/mem5.test diff --git a/manifest b/manifest index 6e716ca725..1606e30842 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Omit\sunnecessary\sOP_Next\sand\sOP_Prev\soperators\swhen\suniqueness\sconstraints\nguarantee\sthat\sthe\scode\swill\sonly\smake\sone\spass\sthrough\sthe\sloop. -D 2011-03-09T21:02:31.691 +C Fix\sissue\swith\smem5\sallocator\swhen\smin\srequest\ssize\sis\slarger\sthatn\s2^30. +D 2011-03-09T21:36:17.288 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,13 +143,13 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e -F src/main.c 93d0d967d6898fc0408ece248342342e312aa753 +F src/main.c b43dc11c8335ceb759d48358ddafe09f02b18a1d F src/malloc.c 92d59a007d7a42857d4e9454aa25b6b703286be1 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 9b237d911ba9904142a804be727cc6664873f8a3 -F src/mem5.c 6fe00f46997bebb690397cb029719f711e7640e3 +F src/mem5.c ebc2530757a9b0f44b61a899aef0109effd55ce8 F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6 F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d @@ -181,7 +178,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in 82274d7f4440b99a80d8cc4f077547fd0b596017 +F src/sqlite.h.in 369c767e6b9f101d63d8e4c5e40279f975ccec08 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 @@ -562,6 +559,7 @@ F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9 F test/malloc_common.tcl 660b82ab528521cc4a48ff6df05ca3b6a00d47c5 F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c +F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test 0825155b2290e900264daaaf0334b6dfe69ea498 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test 679db68394a5692791737b150852173b3e2fea10 @@ -914,14 +912,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P dc46156a2237701679433779b871844f4f2abe4b -R 6a96206125f553ae6e4986479b4fa19e -U drh -Z 3c4f85bbdfea18f22f89d0b2d92c8936 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNd+rroxKgR168RlERAk+tAJ9jEIHTwnjObklOR5pMe4sV08k4IgCeI8br -wFEqDe541wz3+xTQUIuHIUY= -=D87j ------END PGP SIGNATURE----- +P f000c9b2b7348238fe2085140d2dd05294a19709 +R 5c4a42c07b3ab928630b72159bbdf550 +U shaneh +Z 82918d77f73b87eb8c0dd11fedd7903d diff --git a/manifest.uuid b/manifest.uuid index 8d40b7424d..dfe5c5375a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f000c9b2b7348238fe2085140d2dd05294a19709 \ No newline at end of file +d7dae06fb2d57ed6b9555b774712f42077ae4155 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 833b9812b0..1329ae27a9 100644 --- a/src/main.c +++ b/src/main.c @@ -375,6 +375,13 @@ int sqlite3_config(int op, ...){ sqlite3GlobalConfig.nHeap = va_arg(ap, int); sqlite3GlobalConfig.mnReq = va_arg(ap, int); + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ + /* cap min request size at 2^12 */ + sqlite3GlobalConfig.mnReq = (1<<12); + } + if( sqlite3GlobalConfig.pHeap==0 ){ /* If the heap pointer is NULL, then restore the malloc implementation ** back to NULL pointers too. This will cause the malloc to go diff --git a/src/mem5.c b/src/mem5.c index 2fdfac1413..13310be2b0 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -442,7 +442,7 @@ static int memsys5Roundup(int n){ */ static int memsys5Log(int iValue){ int iLog; - for(iLog=0; (1<0 && nMinLog<=(1<<12) ); + nMinLog = memsys5Log(nMinLog); mem5.szAtom = (1<mem5.szAtom ){ mem5.szAtom = mem5.szAtom << 1; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ebabee8ed7..179ae98e20 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1360,7 +1360,9 @@ struct sqlite3_mem_methods { ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory ** allocator is engaged to handle all of SQLites memory allocation needs. ** The first pointer (the memory pointer) must be aligned to an 8-byte -** boundary or subsequent behavior of SQLite will be undefined. +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2^12. Reasonable values +** for the minimum allocation size are 2^5 through 2^8. ** **
SQLITE_CONFIG_MUTEX
**
^(This option takes a single argument which is a pointer to an diff --git a/test/mem5.test b/test/mem5.test new file mode 100644 index 0000000000..6365f1c64b --- /dev/null +++ b/test/mem5.test @@ -0,0 +1,66 @@ +# 2011 March 9 +# +# 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 of the mem5 allocation subsystem. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !mem5 { + finish_test + return +} + +# The tests in this file configure the lookaside allocator after a +# connection is opened. This will not work if there is any "presql" +# configured (SQL run within the [sqlite3] wrapper in tester.tcl). +if {[info exists ::G(perm:presql)]} { + finish_test + return +} + +do_test mem5-1.1 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 25000000 0 + sqlite3_config_lookaside 0 0 + sqlite3_initialize +} {SQLITE_OK} + +# try with min request size = 2^30 +do_test mem5-1.2 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 1 1073741824 + sqlite3_config_lookaside 0 0 + sqlite3_initialize +} {SQLITE_NOMEM} + +# try with min request size = 2^30+1 +# previously this was causing the memsys5Log() func to infinitely loop. +do_test mem5-1.3 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 1 1073741825 + sqlite3_config_lookaside 0 0 + sqlite3_initialize +} {SQLITE_NOMEM} + +do_test mem5-1.4 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 0 0 + sqlite3_config_lookaside 0 0 + sqlite3_initialize +} {SQLITE_OK} + +finish_test From 9324794e1efa8566671fb7607136c515f53022ce Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 10 Mar 2011 03:54:55 +0000 Subject: [PATCH 20/35] Minor clean-up of previous mem5 allocator fix. FossilOrigin-Name: 3643842316239ff7859f0ec522736a2b9c03d22c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/mem5.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1606e30842..f7c483dc57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sissue\swith\smem5\sallocator\swhen\smin\srequest\ssize\sis\slarger\sthatn\s2^30. -D 2011-03-09T21:36:17.288 +C Minor\sclean-up\sof\sprevious\smem5\sallocator\sfix. +D 2011-03-10T03:54:55.462 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -149,7 +149,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 9b237d911ba9904142a804be727cc6664873f8a3 -F src/mem5.c ebc2530757a9b0f44b61a899aef0109effd55ce8 +F src/mem5.c 72e0bc40f535ac38a11712aed01d0014f9300732 F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6 F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d @@ -912,7 +912,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f000c9b2b7348238fe2085140d2dd05294a19709 -R 5c4a42c07b3ab928630b72159bbdf550 +P d7dae06fb2d57ed6b9555b774712f42077ae4155 +R 09ce3b3c494c7ecbffa2cbbcd0f16adf U shaneh -Z 82918d77f73b87eb8c0dd11fedd7903d +Z 8a07294df458a912085e72ad9cffeba4 diff --git a/manifest.uuid b/manifest.uuid index dfe5c5375a..953c410c6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d7dae06fb2d57ed6b9555b774712f42077ae4155 \ No newline at end of file +3643842316239ff7859f0ec522736a2b9c03d22c \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index 13310be2b0..5d6a5b5806 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -442,7 +442,7 @@ static int memsys5Roundup(int n){ */ static int memsys5Log(int iValue){ int iLog; - for(iLog=0; (iLog<((sizeof(int)*8)-2)) && (1<0 && nMinLog<=(1<<12) ); - nMinLog = memsys5Log(nMinLog); + nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq); mem5.szAtom = (1<mem5.szAtom ){ mem5.szAtom = mem5.szAtom << 1; From e08160bdc1160a20a27f8f466e1be0e1deda6ab5 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 10 Mar 2011 21:13:18 +0000 Subject: [PATCH 21/35] Skip unique constraint enforcement if compiled with SQLITE_OMIT_UNIQUE_ENFORCEMENT. FossilOrigin-Name: ba85bf8cb88f7ae220d919f5c23f51d9dcedc843 --- manifest | 15 ++-- manifest.uuid | 2 +- src/insert.c | 10 ++- src/test_config.c | 6 ++ test/omitunique.test | 170 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 test/omitunique.test diff --git a/manifest b/manifest index f7c483dc57..b4381bea7f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sclean-up\sof\sprevious\smem5\sallocator\sfix. -D 2011-03-10T03:54:55.462 +C Skip\sunique\sconstraint\senforcement\sif\scompiled\swith\sSQLITE_OMIT_UNIQUE_ENFORCEMENT. +D 2011-03-10T21:13:18.347 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -138,7 +138,7 @@ F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 036cfac4be398db9dccdf3200a45e3a7260fcfb2 +F src/insert.c 06133d9ea3c17d9adf98a40c87da31dc028759f0 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -198,7 +198,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c 9f025a7f3686c94e82dc6d6bd3cbf0f89cd67487 +F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -584,6 +584,7 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 +F test/omitunique.test f153c7540f2df6dc49c56b97242bda6b60e87fa6 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec F test/oserror.test d1f085bdbac20456fccdf5877f52016453654fc3 F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe @@ -912,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d7dae06fb2d57ed6b9555b774712f42077ae4155 -R 09ce3b3c494c7ecbffa2cbbcd0f16adf +P 3643842316239ff7859f0ec522736a2b9c03d22c +R b1f7b8ea9c365b449d3359fe4224fd3a U shaneh -Z 8a07294df458a912085e72ad9cffeba4 +Z c08bc88ba8510c7d87325ff4426508db diff --git a/manifest.uuid b/manifest.uuid index 953c410c6d..79f5cbdfb7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3643842316239ff7859f0ec522736a2b9c03d22c \ No newline at end of file +ba85bf8cb88f7ae220d919f5c23f51d9dcedc843 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 851f778d48..5a86484b2d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1310,8 +1310,9 @@ void sqlite3GenerateConstraintChecks( */ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ int regIdx; +#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT int regR; - +#endif if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */ /* Create a key for accessing the index entry */ @@ -1329,6 +1330,12 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT + pIdx->onError = OE_None; + sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); + continue; /* Treat pIdx as if it is not a UNIQUE index */ +#else + /* Find out what action to take in case there is an indexing conflict */ onError = pIdx->onError; if( onError==OE_None ){ @@ -1402,6 +1409,7 @@ void sqlite3GenerateConstraintChecks( } sqlite3VdbeJumpHere(v, j3); sqlite3ReleaseTempReg(pParse, regR); +#endif } if( pbMayReplace ){ diff --git a/src/test_config.c b/src/test_config.c index def12a9afc..6eee524c09 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -475,6 +475,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT + Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_UTF16 Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); #else diff --git a/test/omitunique.test b/test/omitunique.test new file mode 100644 index 0000000000..633aaa07d0 --- /dev/null +++ b/test/omitunique.test @@ -0,0 +1,170 @@ +# 2011 March 10 +# +# 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 the SQLITE_OMIT_UNIQUE_ENFORCEMENT +# compiler option. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# table with UNIQUE keyword on column +do_test omitunique-1.1.1 { + catchsql {CREATE TABLE t1(a TEXT UNIQUE); } +} {0 {}} +do_test omitunique-1.1.2 { + catchsql {INSERT INTO t1(a) VALUES('abc'); } +} {0 {}} +do_test omitunique-1.1.3 { + catchsql {INSERT INTO t1(a) VALUES('123'); } +} {0 {}} + +# table with UNIQUE index on column +do_test omitunique-1.2.1 { + catchsql { + CREATE TABLE t2(a TEXT); + CREATE UNIQUE INDEX t2a ON t2(a); + } +} {0 {}} +do_test omitunique-1.2.2 { + catchsql {INSERT INTO t2(a) VALUES('abc'); } +} {0 {}} +do_test omitunique-1.2.3 { + catchsql {INSERT INTO t2(a) VALUES('123'); } +} {0 {}} + +# table with regular index on column +do_test omitunique-1.3.1 { + catchsql { + CREATE TABLE t3(a TEXT); + CREATE INDEX t3a ON t3(a); + } +} {0 {}} +do_test omitunique-1.3.2 { + catchsql {INSERT INTO t3(a) VALUES('abc'); } +} {0 {}} +do_test omitunique-1.3.3 { + catchsql {INSERT INTO t3(a) VALUES('123'); } +} {0 {}} + +# table with no index on column +do_test omitunique-1.4.1 { + catchsql { + CREATE TABLE t4(a TEXT); + } +} {0 {}} +do_test omitunique-1.4.2 { + catchsql {INSERT INTO t4(a) VALUES('abc'); } +} {0 {}} +do_test omitunique-1.4.3 { + catchsql {INSERT INTO t4(a) VALUES('123'); } +} {0 {}} + +# run our tests using several table/index forms +foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { +1 {t1} 1 1 9 1 +2 {t2} 1 1 9 1 +3 {t3} 0 9 9 10 +4 {t4} 0 9 9 100000 +} { + + # check various INSERT commands + foreach {i cmd err} { + 1 {INSERT} 1 + 2 {INSERT OR IGNORE} 0 + 3 {INSERT OR REPLACE} 0 + 4 {REPLACE} 0 + 5 {INSERT OR FAIL} 1 + 6 {INSERT OR ABORT} 1 + 7 {INSERT OR ROLLBACK} 1 + } { + + if { $uniq==0 || $err==0 } { + set msg {0 {}} + } { + set msg {1 {column a is not unique}} + } + + ifcapable unique_enforcement { + ifcapable explain { + do_test omitunique-2.1.$j.$i.1 { + set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] + regexp { IsUnique } $x + } $uniq + } + do_test omitunique-2.1.$j.$i.2 { + catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc')}] + } $msg + } + ifcapable !unique_enforcement { + ifcapable explain { + do_test omitunique-2.1.$j.$i.1 { + set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] + regexp { IsUnique } $x + } {0} + } + do_test omitunique-2.1.$j.$i.2 { + catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc')}] + } {0 {}} + } + + } + # end foreach cmd + + # check UPDATE command + ifcapable unique_enforcement { + ifcapable explain { + do_test omitunique-2.2.$j.1 { + set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] + regexp { IsUnique } $x + } $uniq + } + do_test omitunique-2.2.$j.2 { + catchsql [ subst {UPDATE $tbl SET a='abc'}] + } $msg + } + ifcapable !unique_enforcement { + ifcapable explain { + do_test omitunique-2.2.$j.1 { + set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] + regexp { IsUnique } $x + } {0} + } + do_test omitunique-2.2.$j.2 { + catchsql [ subst {UPDATE $tbl SET a='abc' }] + } {0 {}} + } + + # check record counts + ifcapable unique_enforcement { + do_test omitunique-2.3.$j { + execsql [ subst {SELECT count(*) FROM $tbl WHERE a='abc' }] + } $cnt_enforce + } + ifcapable !unique_enforcement { + do_test omitunique-2.3.$j { + execsql [ subst {SELECT count(*) FROM $tbl WHERE a='abc' }] + } $cnt_omit + } + + # make sure the query planner row estimate not affected because of omit enforcement + ifcapable explain { + do_test omitunique-2.4.$j { + set x [execsql [ subst {EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc' }]] + set y [ subst {~$qp_est row} ] + regexp $y $x + } {1} + } + +} +# end foreach tbl + +finish_test From fbf34bf7947dc3a805ea2104bc208983a7ed8a51 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 10 Mar 2011 21:48:02 +0000 Subject: [PATCH 22/35] Simplification of tests and more added for SQLITE_OMIT_UNIQUE_ENFORCEMENT tests. FossilOrigin-Name: 75a38411a89bd2969ec5cecca13c13a390b3d478 --- manifest | 12 +++--- manifest.uuid | 2 +- test/omitunique.test | 99 ++++++++++++++++++++++++-------------------- 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index b4381bea7f..babc6cadde 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Skip\sunique\sconstraint\senforcement\sif\scompiled\swith\sSQLITE_OMIT_UNIQUE_ENFORCEMENT. -D 2011-03-10T21:13:18.347 +C Simplification\sof\stests\sand\smore\sadded\sfor\sSQLITE_OMIT_UNIQUE_ENFORCEMENT\stests. +D 2011-03-10T21:48:02.401 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -584,7 +584,7 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 -F test/omitunique.test f153c7540f2df6dc49c56b97242bda6b60e87fa6 +F test/omitunique.test 03747013c870bb4c14c3fbaeb13dae8c6efad9f2 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec F test/oserror.test d1f085bdbac20456fccdf5877f52016453654fc3 F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3643842316239ff7859f0ec522736a2b9c03d22c -R b1f7b8ea9c365b449d3359fe4224fd3a +P ba85bf8cb88f7ae220d919f5c23f51d9dcedc843 +R 62d3b55d8406e6fbbc3a5bfec0a6bc04 U shaneh -Z c08bc88ba8510c7d87325ff4426508db +Z 0d4d7d2864ef8876819acc631335ab7b diff --git a/manifest.uuid b/manifest.uuid index 79f5cbdfb7..67b1ecec7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba85bf8cb88f7ae220d919f5c23f51d9dcedc843 \ No newline at end of file +75a38411a89bd2969ec5cecca13c13a390b3d478 \ No newline at end of file diff --git a/test/omitunique.test b/test/omitunique.test index 633aaa07d0..1ed6726e0f 100644 --- a/test/omitunique.test +++ b/test/omitunique.test @@ -16,6 +16,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set uniq_enforced 1 +ifcapable !unique_enforcement { + set uniq_enforced 0 +} + # table with UNIQUE keyword on column do_test omitunique-1.1.1 { catchsql {CREATE TABLE t1(a TEXT UNIQUE); } @@ -87,61 +92,65 @@ foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { 7 {INSERT OR ROLLBACK} 1 } { - if { $uniq==0 || $err==0 } { - set msg {0 {}} + ifcapable explain { + ifcapable unique_enforcement { + do_test omitunique-2.1.$j.$i.1 { + set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] + regexp { IsUnique } $x + } $uniq + } + ifcapable !unique_enforcement { + do_test omitunique-2.1.$j.$i.1 { + set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] + regexp { IsUnique } $x + } {0} + } + do_test omitunique-2.1.$j.2 { + set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] + regexp { Next } $x + } {0} + } + + if { $uniq_enforced==0 || $uniq==0 || $err==0 } { + set msg {0 {}} } { set msg {1 {column a is not unique}} } - - ifcapable unique_enforcement { - ifcapable explain { - do_test omitunique-2.1.$j.$i.1 { - set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] - regexp { IsUnique } $x - } $uniq - } - do_test omitunique-2.1.$j.$i.2 { - catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc')}] - } $msg - } - ifcapable !unique_enforcement { - ifcapable explain { - do_test omitunique-2.1.$j.$i.1 { - set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] - regexp { IsUnique } $x - } {0} - } - do_test omitunique-2.1.$j.$i.2 { - catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc')}] - } {0 {}} - } + do_test omitunique-2.1.$j.$i.3 { + catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc')}] + } $msg } # end foreach cmd # check UPDATE command - ifcapable unique_enforcement { - ifcapable explain { - do_test omitunique-2.2.$j.1 { - set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] - regexp { IsUnique } $x - } $uniq + ifcapable explain { + ifcapable unique_enforcement { + do_test omitunique-2.2.$j.1 { + set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] + regexp { IsUnique } $x + } $uniq } - do_test omitunique-2.2.$j.2 { - catchsql [ subst {UPDATE $tbl SET a='abc'}] - } $msg - } - ifcapable !unique_enforcement { - ifcapable explain { - do_test omitunique-2.2.$j.1 { - set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] - regexp { IsUnique } $x - } {0} + ifcapable !unique_enforcement { + do_test omitunique-2.2.$j.1 { + set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] + regexp { IsUnique } $x + } {0} } - do_test omitunique-2.2.$j.2 { - catchsql [ subst {UPDATE $tbl SET a='abc' }] - } {0 {}} +# comment out for now +# do_test omitunique-2.2.$j.2 { +# set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc' WHERE a<>'abc'}]] +# regexp { Next } $x +# } {0} } + if { $uniq_enforced==0 || $uniq==0 } { + set msg {0 {}} + } { + set msg {1 {column a is not unique}} + } + do_test omitunique-2.2.$j.3 { + catchsql [ subst {UPDATE $tbl SET a='abc'}] + } $msg # check record counts ifcapable unique_enforcement { @@ -158,7 +167,7 @@ foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { # make sure the query planner row estimate not affected because of omit enforcement ifcapable explain { do_test omitunique-2.4.$j { - set x [execsql [ subst {EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc' }]] + set x [ execsql [ subst {EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc' }]] set y [ subst {~$qp_est row} ] regexp $y $x } {1} From ca6b9d5bbed35d6cf743d8d63b14412391983ec0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Mar 2011 16:15:48 +0000 Subject: [PATCH 23/35] Remove an unused field from the unix sqlite3_file object. FossilOrigin-Name: f957f23a8a392bb1720720960bda2c7b24de9663 --- manifest | 24 +++++++++++++++++------- manifest.uuid | 2 +- src/os_unix.c | 7 ------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index babc6cadde..8ef1bb0a6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Simplification\sof\stests\sand\smore\sadded\sfor\sSQLITE_OMIT_UNIQUE_ENFORCEMENT\stests. -D 2011-03-10T21:48:02.401 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Remove\san\sunused\sfield\sfrom\sthe\sunix\ssqlite3_file\sobject. +D 2011-03-11T16:15:48.132 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -162,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf -F src/os_unix.c 58fe8845678f6a4e30ed6988c5df7327bc7bd69b +F src/os_unix.c c4d50608133e16185dd2e120d2713c096f390260 F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -913,7 +916,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ba85bf8cb88f7ae220d919f5c23f51d9dcedc843 -R 62d3b55d8406e6fbbc3a5bfec0a6bc04 -U shaneh -Z 0d4d7d2864ef8876819acc631335ab7b +P 75a38411a89bd2969ec5cecca13c13a390b3d478 +R 7f2984260ffacb3dffcb8dcb5c4023c8 +U drh +Z d9c90b8af5c4c55409cdd40572c1521c +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFNekq3oxKgR168RlERAnw2AJwJjXruLGtJKxCByVRypbB2NPpZ+ACfTrqn +vTIXWbkq8AxcjkytK9CY6es= +=V2tY +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 67b1ecec7c..36d1255651 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75a38411a89bd2969ec5cecca13c13a390b3d478 \ No newline at end of file +f957f23a8a392bb1720720960bda2c7b24de9663 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 335fcae99c..0d72802bdf 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -209,7 +209,6 @@ struct unixFile { int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ - int fileFlags; /* Miscellanous flags */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ @@ -243,11 +242,6 @@ struct unixFile { #endif }; -/* -** The following macros define bits in unixFile.fileFlags -*/ -#define SQLITE_WHOLE_FILE_LOCKING 0x0001 /* Use whole-file locking */ - /* ** Include code that is common to all os_*.c files */ @@ -4356,7 +4350,6 @@ static int fillInUnixFile( OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; pNew->dirfd = dirfd; - pNew->fileFlags = 0; pNew->zPath = zFilename; #if OS_VXWORKS From 11c58f7d8e3b17c674acbfc2ce5b51c0e71121e2 Mon Sep 17 00:00:00 2001 From: shaneh Date: Sat, 12 Mar 2011 04:58:55 +0000 Subject: [PATCH 24/35] More tests for SQLITE_OMIT_UNIQUE_ENFORCEMENT and minor change to implementation. FossilOrigin-Name: b86999436ec2414c990ba720441fe316f647eef6 --- manifest | 30 ++++------- manifest.uuid | 2 +- src/ctime.c | 3 ++ src/insert.c | 1 - test/omitunique.test | 123 ++++++++++++++++++++----------------------- tool/omittest.tcl | 1 + 6 files changed, 72 insertions(+), 88 deletions(-) diff --git a/manifest b/manifest index 8ef1bb0a6e..f956375794 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Remove\san\sunused\sfield\sfrom\sthe\sunix\ssqlite3_file\sobject. -D 2011-03-11T16:15:48.132 +C More\stests\sfor\sSQLITE_OMIT_UNIQUE_ENFORCEMENT\sand\sminor\schange\sto\simplementation. +D 2011-03-12T04:58:55.547 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +127,7 @@ F src/btreeInt.h 20f73dc93b1eeb83afd7259fbc6bd7dcf2df7fe4 F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d F src/callback.c a1d1b1c9c85415dff013af033e2fed9c8382d33b F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac -F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 +F src/ctime.c 52ff72f966cee3087e0138a3ec69371c22be3c01 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd F src/expr.c 00817c672af554321fd67c44325afd7cef0e4648 @@ -141,7 +138,7 @@ F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 06133d9ea3c17d9adf98a40c87da31dc028759f0 +F src/insert.c 8ffb544ff516669aa84a6f13d05dbf5c93bdb1ea F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -587,7 +584,7 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 -F test/omitunique.test 03747013c870bb4c14c3fbaeb13dae8c6efad9f2 +F test/omitunique.test bbb2ec4345d9125d9ee21cd9488d97a163020d5f F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec F test/oserror.test d1f085bdbac20456fccdf5877f52016453654fc3 F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe @@ -896,7 +893,7 @@ F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87 -F tool/omittest.tcl 71c6f21afa2df91dd299ed317d5751fb628795fe +F tool/omittest.tcl 4f4cc66bb7ca6a5b8f61ee37b6333f60fb8a746a F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/shell1.test f608a009b04c490fd360c5ded458a6f98b4e7ec4 @@ -916,14 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 75a38411a89bd2969ec5cecca13c13a390b3d478 -R 7f2984260ffacb3dffcb8dcb5c4023c8 -U drh -Z d9c90b8af5c4c55409cdd40572c1521c ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNekq3oxKgR168RlERAnw2AJwJjXruLGtJKxCByVRypbB2NPpZ+ACfTrqn -vTIXWbkq8AxcjkytK9CY6es= -=V2tY ------END PGP SIGNATURE----- +P f957f23a8a392bb1720720960bda2c7b24de9663 +R 9809ca6e3f2473669b6771844893033b +U shaneh +Z 165de3d9f760ec4796ef397e07022985 diff --git a/manifest.uuid b/manifest.uuid index 36d1255651..1dab3e6dc1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f957f23a8a392bb1720720960bda2c7b24de9663 \ No newline at end of file +b86999436ec2414c990ba720441fe316f647eef6 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index a128f61a69..a04c567b40 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -302,6 +302,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION "OMIT_TRUNCATE_OPTIMIZATION", #endif +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT + "OMIT_UNIQUE_ENFORCEMENT", +#endif #ifdef SQLITE_OMIT_UTF16 "OMIT_UTF16", #endif diff --git a/src/insert.c b/src/insert.c index 5a86484b2d..a4efcf2bf3 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1331,7 +1331,6 @@ void sqlite3GenerateConstraintChecks( sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); #ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT - pIdx->onError = OE_None; sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); continue; /* Treat pIdx as if it is not a UNIQUE index */ #else diff --git a/test/omitunique.test b/test/omitunique.test index 1ed6726e0f..83a2a95bdc 100644 --- a/test/omitunique.test +++ b/test/omitunique.test @@ -22,65 +22,52 @@ ifcapable !unique_enforcement { } # table with UNIQUE keyword on column -do_test omitunique-1.1.1 { - catchsql {CREATE TABLE t1(a TEXT UNIQUE); } +do_test omitunique-1.1 { + catchsql { CREATE TABLE t1(a TEXT UNIQUE); } } {0 {}} -do_test omitunique-1.1.2 { - catchsql {INSERT INTO t1(a) VALUES('abc'); } -} {0 {}} -do_test omitunique-1.1.3 { - catchsql {INSERT INTO t1(a) VALUES('123'); } + +# table with UNIQUE clause on column +do_test omitunique-1.2 { + catchsql { CREATE TABLE t2(a TEXT, UNIQUE(a)); } } {0 {}} # table with UNIQUE index on column -do_test omitunique-1.2.1 { +do_test omitunique-1.3 { catchsql { - CREATE TABLE t2(a TEXT); - CREATE UNIQUE INDEX t2a ON t2(a); + CREATE TABLE t3(a TEXT); + CREATE UNIQUE INDEX t3a ON t3(a); } } {0 {}} -do_test omitunique-1.2.2 { - catchsql {INSERT INTO t2(a) VALUES('abc'); } -} {0 {}} -do_test omitunique-1.2.3 { - catchsql {INSERT INTO t2(a) VALUES('123'); } -} {0 {}} # table with regular index on column -do_test omitunique-1.3.1 { +do_test omitunique-1.4 { catchsql { - CREATE TABLE t3(a TEXT); - CREATE INDEX t3a ON t3(a); + CREATE TABLE t4(a TEXT); + CREATE INDEX t4a ON t4(a); } } {0 {}} -do_test omitunique-1.3.2 { - catchsql {INSERT INTO t3(a) VALUES('abc'); } -} {0 {}} -do_test omitunique-1.3.3 { - catchsql {INSERT INTO t3(a) VALUES('123'); } -} {0 {}} # table with no index on column -do_test omitunique-1.4.1 { - catchsql { - CREATE TABLE t4(a TEXT); - } -} {0 {}} -do_test omitunique-1.4.2 { - catchsql {INSERT INTO t4(a) VALUES('abc'); } -} {0 {}} -do_test omitunique-1.4.3 { - catchsql {INSERT INTO t4(a) VALUES('123'); } +do_test omitunique-1.5 { + catchsql { CREATE TABLE t5(a TEXT); } } {0 {}} # run our tests using several table/index forms -foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { -1 {t1} 1 1 9 1 -2 {t2} 1 1 9 1 -3 {t3} 0 9 9 10 -4 {t4} 0 9 9 100000 +foreach {j tbl uniq cnt qp_est stat_enforce stat_omit } { +1 {t1} 1 1 1 {2 1} {9 9} +2 {t2} 1 1 1 {2 1} {9 9} +3 {t3} 1 1 1 {2 1} {9 9} +4 {t4} 0 9 10 {9 9} {9 9} +5 {t5} 0 9 100000 9 9 } { + do_test omitunique-2.0.$j.1 { + catchsql [ subst {INSERT INTO $tbl (a) VALUES('abc'); }] + } {0 {}} + do_test omitunique-2.0.$j.2 { + catchsql [ subst {INSERT INTO $tbl (a) VALUES('123'); }] + } {0 {}} + # check various INSERT commands foreach {i cmd err} { 1 {INSERT} 1 @@ -93,22 +80,17 @@ foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { } { ifcapable explain { + set x [execsql [ subst { EXPLAIN $cmd INTO $tbl (a) VALUES('abc'); }]] ifcapable unique_enforcement { do_test omitunique-2.1.$j.$i.1 { - set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] regexp { IsUnique } $x } $uniq } ifcapable !unique_enforcement { do_test omitunique-2.1.$j.$i.1 { - set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] regexp { IsUnique } $x } {0} } - do_test omitunique-2.1.$j.2 { - set x [execsql [ subst {EXPLAIN $cmd INTO $tbl (a) VALUES('abc')}]] - regexp { Next } $x - } {0} } if { $uniq_enforced==0 || $uniq==0 || $err==0 } { @@ -117,7 +99,7 @@ foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { set msg {1 {column a is not unique}} } do_test omitunique-2.1.$j.$i.3 { - catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc')}] + catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc'); }] } $msg } @@ -125,23 +107,17 @@ foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { # check UPDATE command ifcapable explain { + set x [execsql [ subst { EXPLAIN UPDATE $tbl SET a='abc'; }]] ifcapable unique_enforcement { do_test omitunique-2.2.$j.1 { - set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] regexp { IsUnique } $x } $uniq } ifcapable !unique_enforcement { do_test omitunique-2.2.$j.1 { - set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc'}]] regexp { IsUnique } $x } {0} } -# comment out for now -# do_test omitunique-2.2.$j.2 { -# set x [execsql [ subst {EXPLAIN UPDATE $tbl SET a='abc' WHERE a<>'abc'}]] -# regexp { Next } $x -# } {0} } if { $uniq_enforced==0 || $uniq==0 } { set msg {0 {}} @@ -149,30 +125,45 @@ foreach {j tbl uniq cnt_enforce cnt_omit qp_est} { set msg {1 {column a is not unique}} } do_test omitunique-2.2.$j.3 { - catchsql [ subst {UPDATE $tbl SET a='abc'}] + catchsql [ subst { UPDATE $tbl SET a='abc'; }] } $msg # check record counts - ifcapable unique_enforcement { - do_test omitunique-2.3.$j { - execsql [ subst {SELECT count(*) FROM $tbl WHERE a='abc' }] - } $cnt_enforce - } - ifcapable !unique_enforcement { - do_test omitunique-2.3.$j { - execsql [ subst {SELECT count(*) FROM $tbl WHERE a='abc' }] - } $cnt_omit - } + do_test omitunique-2.3.$j { + execsql [ subst { SELECT count(*) FROM $tbl WHERE a='abc'; }] + } $cnt # make sure the query planner row estimate not affected because of omit enforcement ifcapable explain { do_test omitunique-2.4.$j { - set x [ execsql [ subst {EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc' }]] + set x [ execsql [ subst { EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc'; }]] set y [ subst {~$qp_est row} ] regexp $y $x } {1} } + # make sure we omit extra OP_Next opcodes when the UNIQUE constraints + # mean there will only be a single pass through the code + ifcapable explain { + set x [execsql [ subst { EXPLAIN SELECT * FROM $tbl WHERE a='abc'; }]] + do_test omitunique-2.5.$j { + if { [ regexp { Next } $x ] } { expr { 0 } } { expr { 1 } } + } $uniq + } + + # make sure analyze index stats correct + ifcapable analyze { + if { $uniq_enforced==0 } { + set msg [ list $stat_omit ] + } { + set msg [ list $stat_enforce ] + } + do_test omitunique-2.6.$j { + execsql [ subst { ANALYZE $tbl; } ] + execsql [ subst { SELECT stat FROM sqlite_stat1 WHERE tbl='$tbl'; } ] + } $msg + } + } # end foreach tbl diff --git a/tool/omittest.tcl b/tool/omittest.tcl index e03c48690c..e23dbaf4cb 100644 --- a/tool/omittest.tcl +++ b/tool/omittest.tcl @@ -202,6 +202,7 @@ proc main {argv} { SQLITE_OMIT_TRACE \ SQLITE_OMIT_TRIGGER \ SQLITE_OMIT_TRUNCATE_OPTIMIZATION \ + SQLITE_OMIT_UNIQUE_ENFORCEMENT \ SQLITE_OMIT_UTF16 \ SQLITE_OMIT_VACUUM \ SQLITE_OMIT_VIEW \ From a7e61d8b247ded7b5b2283e6b598fb4cc1b7895a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Mar 2011 17:02:57 +0000 Subject: [PATCH 25/35] Add the new optional "unix-excl" VFS. This VFS grabs an exclusive lock on the database preventing other processes from accessing it, but continues to allow other database connections from the same process. FossilOrigin-Name: 00051c3296e11211b2bb5ae28f016b17dca857d7 --- manifest | 30 ++++++++++++++------ manifest.uuid | 2 +- src/os_unix.c | 77 +++++++++++++++++++++++++++++++++++++++++---------- src/shell.c | 13 +++++++++ 4 files changed, 98 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index f956375794..014dfe961b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C More\stests\sfor\sSQLITE_OMIT_UNIQUE_ENFORCEMENT\sand\sminor\schange\sto\simplementation. -D 2011-03-12T04:58:55.547 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Add\sthe\snew\soptional\s"unix-excl"\sVFS.\s\sThis\sVFS\sgrabs\san\sexclusive\slock\son\nthe\sdatabase\spreventing\sother\sprocesses\sfrom\saccessing\sit,\sbut\scontinues\sto\nallow\sother\sdatabase\sconnections\sfrom\sthe\ssame\sprocess. +D 2011-03-12T17:02:57.101 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -162,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf -F src/os_unix.c c4d50608133e16185dd2e120d2713c096f390260 +F src/os_unix.c 557837beff775c448bb072ae21edeff912d1f0df F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -177,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 -F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b +F src/shell.c 54f8fe0afab6839444882c4d18a0032668392c9a F src/sqlite.h.in 369c767e6b9f101d63d8e4c5e40279f975ccec08 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 @@ -913,7 +916,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f957f23a8a392bb1720720960bda2c7b24de9663 -R 9809ca6e3f2473669b6771844893033b -U shaneh -Z 165de3d9f760ec4796ef397e07022985 +P b86999436ec2414c990ba720441fe316f647eef6 +R b4018b4a3ca8304164ff6618b813c5a9 +T *bgcolor * #aaa8d3 +T *branch * unix-excl +T *sym-unix-excl * +T -sym-trunk * +U drh +Z ca346ade739e93ef182345e803581a80 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFNe6dEoxKgR168RlERAkgMAJ47rTo3YzDvLp8S+pIflXBmm5FOSwCggCkn +s82X2XcH9cqBqUU6lQenClw= +=LUbU +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 1dab3e6dc1..e7ce79f84b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b86999436ec2414c990ba720441fe316f647eef6 \ No newline at end of file +00051c3296e11211b2bb5ae28f016b17dca857d7 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 0d72802bdf..c373ebee6b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -206,6 +206,7 @@ struct unixFile { int h; /* The file descriptor */ int dirfd; /* File descriptor for the directory */ unsigned char eFileLock; /* The type of lock held on this fd */ + unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ @@ -242,6 +243,11 @@ struct unixFile { #endif }; +/* +** Allowed values for the unixFile.ctrlFlags bitmask: +*/ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ + /* ** Include code that is common to all os_*.c files */ @@ -887,7 +893,8 @@ struct unixFileId { struct unixInodeInfo { struct unixFileId fileId; /* The lookup key */ int nShared; /* Number of SHARED locks held */ - int eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ int nRef; /* Number of pointers to this structure */ unixShmNode *pShmNode; /* Shared memory associated with this inode */ int nLock; /* Number of outstanding file locks */ @@ -1158,7 +1165,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ /* Otherwise see if some other process holds it. */ #ifndef __DJGPP__ - if( !reserved ){ + if( !reserved && !pFile->pInode->bProcessLock ){ struct flock lock; lock.l_whence = SEEK_SET; lock.l_start = RESERVED_BYTE; @@ -1181,6 +1188,40 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ return rc; } +/* +** Attempt to set a system-lock on the file pFile. The lock is +** described by pLock. +** +** If the pFile was opened from unix-excl, then the only lock ever +** obtained is an exclusive lock, and it is obtained exactly once +** the first time any lock is attempted. All subsequent system locking +** operations become no-ops. Locking operations still happen internally, +** in order to coordinate access between separate database connections +** within this process, but all of that is handled in memory and the +** operating system does not participate. +*/ +static int unixFileLock(unixFile *pFile, struct flock *pLock){ + int rc; + assert( unixMutexHeld() ); + if( (pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pFile->pInode->bProcessLock ){ + if( pFile->pInode->bProcessLock==0 ){ + struct flock lock; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + lock.l_type = F_WRLCK; + rc = osFcntl(pFile->h, F_SETLK, &lock); + if( rc<0 ) return rc; + pFile->pInode->bProcessLock = 1; + }else{ + rc = 0; + } + }else{ + rc = osFcntl(pFile->h, F_SETLK, pLock); + } + return rc; +} + /* ** Lock the file with the lock specified by parameter eFileLock - one ** of the following: @@ -1317,7 +1358,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ){ lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); lock.l_start = PENDING_BYTE; - s = osFcntl(pFile->h, F_SETLK, &lock); + s = unixFileLock(pFile, &lock); if( s==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); @@ -1339,14 +1380,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){ /* Now get the read-lock */ lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( (s = osFcntl(pFile->h, F_SETLK, &lock))==(-1) ){ + if( (s = unixFileLock(pFile, &lock))==(-1) ){ tErrno = errno; } /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; - if( osFcntl(pFile->h, F_SETLK, &lock)!=0 ){ + if( unixFileLock(pFile, &lock)!=0 ){ if( s != -1 ){ /* This could happen with a network mount */ tErrno = errno; @@ -1389,7 +1430,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ default: assert(0); } - s = osFcntl(pFile->h, F_SETLK, &lock); + s = unixFileLock(pFile, &lock); if( s==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); @@ -1458,7 +1499,7 @@ static void setPendingFd(unixFile *pFile){ ** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to ** remove the write lock on a region when a read lock is set. */ -static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode; struct flock lock; @@ -1525,7 +1566,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; - if( osFcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile,, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1537,7 +1578,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; - if( osFcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1549,7 +1590,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST+divSize; lock.l_len = SHARED_SIZE-divSize; - if( osFcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1564,7 +1605,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; - if( osFcntl(h, F_SETLK, &lock)==(-1) ){ + if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ @@ -1578,7 +1619,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - if( osFcntl(h, F_SETLK, &lock)!=(-1) ){ + if( unixFileLock(pFile, &lock)!=(-1) ){ pInode->eFileLock = SHARED_LOCK; }else{ tErrno = errno; @@ -1602,7 +1643,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); - if( osFcntl(h, F_SETLK, &lock)!=(-1) ){ + if( unixFileLock(pFile, &lock)!=(-1) ){ pInode->eFileLock = NO_LOCK; }else{ tErrno = errno; @@ -1640,7 +1681,7 @@ end_unlock: ** the requested locking level, this routine is a no-op. */ static int unixUnlock(sqlite3_file *id, int eFileLock){ - return _posixUnlock(id, eFileLock, 0); + return posixUnlock(id, eFileLock, 0); } /* @@ -2821,7 +2862,7 @@ static int afpClose(sqlite3_file *id) { ** the requested locking level, this routine is a no-op. */ static int nfsUnlock(sqlite3_file *id, int eFileLock){ - return _posixUnlock(id, eFileLock, 1); + return posixUnlock(id, eFileLock, 1); } #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ @@ -4351,6 +4392,11 @@ static int fillInUnixFile( pNew->h = h; pNew->dirfd = dirfd; pNew->zPath = zFilename; + if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ + pNew->ctrlFlags = UNIXFILE_EXCL; + }else{ + pNew->ctrlFlags = 0; + } #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); @@ -6550,6 +6596,7 @@ int sqlite3_os_init(void){ #endif UNIXVFS("unix-none", nolockIoFinder ), UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-excl", posixIoFinder ), #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif diff --git a/src/shell.c b/src/shell.c index 82bb20f5e0..a617c06795 100644 --- a/src/shell.c +++ b/src/shell.c @@ -419,6 +419,7 @@ struct callback_data { ** .explain ON */ char outfile[FILENAME_MAX]; /* Filename for *out */ const char *zDbFilename; /* name of the database file */ + const char *zVfs; /* Name of VFS to use */ sqlite3_stmt *pStmt; /* Current statement if any. */ FILE *pLog; /* Write log output here */ }; @@ -2600,6 +2601,7 @@ static const char zOptions[] = " -stats print memory stats before each finalize\n" " -nullvalue 'text' set text string for NULL values\n" " -version show SQLite version\n" + " -vfs NAME use NAME as the default VFS\n" ; static void usage(int showDetail){ fprintf(stderr, @@ -2684,6 +2686,15 @@ int main(int argc, char **argv){ #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); #endif + }else if( strcmp(argv[i],"-vfs")==0 ){ + i++; + sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[i]); + if( pVfs ){ + sqlite3_vfs_register(pVfs, 1); + }else{ + fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]); + exit(1); + } } } if( i Date: Sat, 12 Mar 2011 18:10:44 +0000 Subject: [PATCH 26/35] In the "unix-excl" VFS, use the heap for shared memory, since only a single process is able to read or write the database. FossilOrigin-Name: a05a6d40875df674f9c2b46e33128c6878d4edaa --- manifest | 22 +++----- manifest.uuid | 2 +- src/os_unix.c | 150 +++++++++++++++++++++++++++++++------------------- 3 files changed, 104 insertions(+), 70 deletions(-) diff --git a/manifest b/manifest index 014dfe961b..053cef99a8 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\sthe\snew\soptional\s"unix-excl"\sVFS.\s\sThis\sVFS\sgrabs\san\sexclusive\slock\son\nthe\sdatabase\spreventing\sother\sprocesses\sfrom\saccessing\sit,\sbut\scontinues\sto\nallow\sother\sdatabase\sconnections\sfrom\sthe\ssame\sprocess. -D 2011-03-12T17:02:57.101 +C In\sthe\s"unix-excl"\sVFS,\suse\sthe\sheap\sfor\sshared\smemory,\ssince\sonly\sa\ssingle\nprocess\sis\sable\sto\sread\sor\swrite\sthe\sdatabase. +D 2011-03-12T18:10:44.973 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf -F src/os_unix.c 557837beff775c448bb072ae21edeff912d1f0df +F src/os_unix.c 1debf5ea6efd0f35335a2a615198a7a1017ffd4b F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -916,18 +916,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P b86999436ec2414c990ba720441fe316f647eef6 -R b4018b4a3ca8304164ff6618b813c5a9 -T *bgcolor * #aaa8d3 -T *branch * unix-excl -T *sym-unix-excl * -T -sym-trunk * +P 00051c3296e11211b2bb5ae28f016b17dca857d7 +R ae21c3eefa2912bdd40576825c99670e U drh -Z ca346ade739e93ef182345e803581a80 +Z 0353c9261ee94db4155a765014c19a0b -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNe6dEoxKgR168RlERAkgMAJ47rTo3YzDvLp8S+pIflXBmm5FOSwCggCkn -s82X2XcH9cqBqUU6lQenClw= -=LUbU +iD8DBQFNe7cnoxKgR168RlERAsDBAJ486IVhWF+3w87MQdsa9IV6+Kk3UQCfVQ5D +gOLo9IyLtbi3pQ3LQfZd9Y8= +=wzQK -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index e7ce79f84b..178e5215aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00051c3296e11211b2bb5ae28f016b17dca857d7 \ No newline at end of file +a05a6d40875df674f9c2b46e33128c6878d4edaa \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index c373ebee6b..246a2d5776 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1202,17 +1202,21 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ */ static int unixFileLock(unixFile *pFile, struct flock *pLock){ int rc; + unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); - if( (pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pFile->pInode->bProcessLock ){ - if( pFile->pInode->bProcessLock==0 ){ + assert( pInode!=0 ); + if( (pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock ){ + if( pInode->bProcessLock==0 ){ struct flock lock; + assert( pInode->nLock==0 ); lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; lock.l_type = F_WRLCK; rc = osFcntl(pFile->h, F_SETLK, &lock); if( rc<0 ) return rc; - pFile->pInode->bProcessLock = 1; + pInode->bProcessLock = 1; + pInode->nLock++; }else{ rc = 0; } @@ -1731,6 +1735,8 @@ static int unixClose(sqlite3_file *id){ unixFile *pFile = (unixFile *)id; unixUnlock(id, NO_LOCK); unixEnterMutex(); + assert( pFile->pInode==0 || pFile->pInode->nLock>0 + || pFile->pInode->bProcessLock==0 ); if( pFile->pInode && pFile->pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file @@ -3559,15 +3565,17 @@ static int unixShmSystemLock( /* Locks are within range */ assert( n>=1 && nh>=0 ){ + /* Initialize the locking parameters */ + memset(&f, 0, sizeof(f)); + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; - rc = osFcntl(pShmNode->h, F_SETLK, &f); - rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + rc = osFcntl(pShmNode->h, F_SETLK, &f); + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + } /* Update the global lock state and do debug tracing */ #ifdef SQLITE_DEBUG @@ -3622,7 +3630,11 @@ static void unixShmPurge(unixFile *pFd){ assert( p->pInode==pFd->pInode ); if( p->mutex ) sqlite3_mutex_free(p->mutex); for(i=0; inRegion; i++){ - munmap(p->apRegion[i], p->szRegion); + if( p->h>=0 ){ + munmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } } sqlite3_free(p->apRegion); if( p->h>=0 ){ @@ -3662,6 +3674,12 @@ static void unixShmPurge(unixFile *pFd){ ** When opening a new shared-memory file, if no other instances of that ** file are currently open, in this process or in other processes, then ** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. */ static int unixOpenSharedMemory(unixFile *pDbFd){ struct unixShm *p = 0; /* The connection to be opened */ @@ -3691,7 +3709,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** with the same permissions. The actual permissions the file is created ** with are subject to the current umask setting. */ - if( osFstat(pDbFd->h, &sStat) ){ + if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ rc = SQLITE_IOERR_FSTAT; goto shm_open_err; } @@ -3724,26 +3742,28 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ goto shm_open_err; } - pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, - (sStat.st_mode & 0777)); - if( pShmNode->h<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); - goto shm_open_err; - } - - /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - rc = SQLITE_OK; - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( robust_ftruncate(pShmNode->h, 0) ){ - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + if( pInode->bProcessLock==0 ){ + pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, + (sStat.st_mode & 0777)); + if( pShmNode->h<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( robust_ftruncate(pShmNode->h, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + } + } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; } - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; } /* Make the new connection a child of the unixShmNode */ @@ -3817,6 +3837,9 @@ static int unixShmMap( pShmNode = p->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); if( pShmNode->nRegion<=iRegion ){ char **apNew; /* New apRegion[] array */ @@ -3825,27 +3848,30 @@ static int unixShmMap( pShmNode->szRegion = szRegion; - /* The requested region is not mapped into this processes address space. - ** Check to see if it has been allocated (i.e. if the wal-index file is - ** large enough to contain the requested region). - */ - if( osFstat(pShmNode->h, &sStat) ){ - rc = SQLITE_IOERR_SHMSIZE; - goto shmpage_out; - } - - if( sStat.st_sizeh>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). */ - if( !bExtend ) goto shmpage_out; - if( robust_ftruncate(pShmNode->h, nByte) ){ - rc = unixLogError(SQLITE_IOERR_SHMSIZE,"ftruncate",pShmNode->zFilename); + if( osFstat(pShmNode->h, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; } + + if( sStat.st_sizeh, nByte) ){ + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate", + pShmNode->zFilename); + goto shmpage_out; + } + } } /* Map the requested memory region into this processes address space. */ @@ -3858,12 +3884,22 @@ static int unixShmMap( } pShmNode->apRegion = apNew; while(pShmNode->nRegion<=iRegion){ - void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, - MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion - ); - if( pMem==MAP_FAILED ){ - rc = SQLITE_IOERR; - goto shmpage_out; + void *pMem; + if( pShmNode->h>=0 ){ + pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion + ); + if( pMem==MAP_FAILED ){ + rc = SQLITE_IOERR; + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc(szRegion); + if( pMem==0 ){ + rc = SQLITE_NOMEM; + goto shmpage_out; + } + memset(pMem, 0, szRegion); } pShmNode->apRegion[pShmNode->nRegion] = pMem; pShmNode->nRegion++; @@ -3910,6 +3946,8 @@ static int unixShmLock( || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); mask = (1<<(ofst+n)) - (1<1 || mask==(1<nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ - if( deleteFlag ) unlink(pShmNode->zFilename); + if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename); unixShmPurge(pDbFd); } unixLeaveMutex(); From 9d677e15992db392950e42fa7e1cc1eb001330dd Mon Sep 17 00:00:00 2001 From: shaneh Date: Tue, 15 Mar 2011 02:55:28 +0000 Subject: [PATCH 27/35] Fix cut-and-paste typo in debugging print statement in winMutexTry(). FossilOrigin-Name: def98fd23e42bda13547e38ab13fed0e6554ce99 --- manifest | 24 +++++++----------------- manifest.uuid | 2 +- src/mutex_w32.c | 2 +- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index ac898a1f5c..a007a938e2 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Merge\sthe\sunix-excl\sVFS\sinto\sthe\strunk.\s\sThis\smerge\salso\sadds\sthe\s-vfs\noption\sto\sthe\scommand-line\sshell. -D 2011-03-14T13:54:01.926 +C Fix\scut-and-paste\stypo\sin\sdebugging\sprint\sstatement\sin\swinMutexTry(). +D 2011-03-15T02:55:28.657 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -159,7 +156,7 @@ F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151 F src/mutex_os2.c f5d09e85b914643c230aa97db709fc0db370d93c F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 -F src/mutex_w32.c 3ade5ae71449d1d023f0ebb3184c2ae6aa9307e4 +F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 @@ -916,14 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P b86999436ec2414c990ba720441fe316f647eef6 a05a6d40875df674f9c2b46e33128c6878d4edaa -R ae21c3eefa2912bdd40576825c99670e -U drh -Z ba80be8ddf09d06ab5258c5662ce63ed ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNfh39oxKgR168RlERAmUtAJ9euZA2mXv2u5a2MP0I1/796quLkACfTDGF -KRyVKh4JS29RnQdWZdfQ0tU= -=K1xX ------END PGP SIGNATURE----- +P 3934b004e93852c89b937ec20431de96a2e99440 +R a3bacb1f22d0b4cfa6cea5cf5efe9cdf +U shaneh +Z 62a7f6dd55f1de5255b8d7f88e967001 diff --git a/manifest.uuid b/manifest.uuid index f958506833..03da2a631d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3934b004e93852c89b937ec20431de96a2e99440 \ No newline at end of file +def98fd23e42bda13547e38ab13fed0e6554ce99 \ No newline at end of file diff --git a/src/mutex_w32.c b/src/mutex_w32.c index 8e257a91b0..bfd9dacf6c 100644 --- a/src/mutex_w32.c +++ b/src/mutex_w32.c @@ -280,7 +280,7 @@ static int winMutexTry(sqlite3_mutex *p){ #endif #ifdef SQLITE_DEBUG if( rc==SQLITE_OK && p->trace ){ - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } #endif return rc; From 77ec9ba3f89d54202d764e53ce1cef3868dcf341 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Mar 2011 18:35:44 +0000 Subject: [PATCH 28/35] Fix an out-of-order variable declaration in shell.c. FossilOrigin-Name: 725708465072fc63736e99610cc9cb0ac336145a --- manifest | 24 +++++++++++++++++------- manifest.uuid | 2 +- src/shell.c | 3 +-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a007a938e2..3f43f7f896 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Fix\scut-and-paste\stypo\sin\sdebugging\sprint\sstatement\sin\swinMutexTry(). -D 2011-03-15T02:55:28.657 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Fix\san\sout-of-order\svariable\sdeclaration\sin\sshell.c. +D 2011-03-15T18:35:44.256 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -177,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 -F src/shell.c 54f8fe0afab6839444882c4d18a0032668392c9a +F src/shell.c ea40658271dfff494dab3dee4a1c0f382d239675 F src/sqlite.h.in 369c767e6b9f101d63d8e4c5e40279f975ccec08 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 @@ -913,7 +916,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3934b004e93852c89b937ec20431de96a2e99440 -R a3bacb1f22d0b4cfa6cea5cf5efe9cdf -U shaneh -Z 62a7f6dd55f1de5255b8d7f88e967001 +P def98fd23e42bda13547e38ab13fed0e6554ce99 +R 2ceb7e2495de2e32fa2e2aca83b58f09 +U drh +Z e7ee1c18a6d623c4d19a0ae664dea8d8 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFNf7GDoxKgR168RlERAhc+AJ9qHfOaDlOtj2TqHpdpAXpIiMjRTwCeP6Tv +esEJjmOwgIx+D+pi9BcOh8Y= +=lte8 +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 03da2a631d..72a3cfb274 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -def98fd23e42bda13547e38ab13fed0e6554ce99 \ No newline at end of file +725708465072fc63736e99610cc9cb0ac336145a \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index a617c06795..34e821ca3d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2687,8 +2687,7 @@ int main(int argc, char **argv){ sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); #endif }else if( strcmp(argv[i],"-vfs")==0 ){ - i++; - sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[i]); + sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]); if( pVfs ){ sqlite3_vfs_register(pVfs, 1); }else{ From 7719711b816ad0cce145161c4870fff53b9948e4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Mar 2011 19:08:48 +0000 Subject: [PATCH 29/35] Make the "unix-excl" VFS work exactly like "unix" if the database file is read-only. FossilOrigin-Name: d9846834993079fb2e42d6bd2644b2154ef324d1 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/os_unix.c | 28 +++++++++++++++++++++------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 3f43f7f896..3441c2202d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\san\sout-of-order\svariable\sdeclaration\sin\sshell.c. -D 2011-03-15T18:35:44.256 +C Make\sthe\s"unix-excl"\sVFS\swork\sexactly\slike\s"unix"\sif\sthe\sdatabase\nfile\sis\sread-only. +D 2011-03-15T19:08:48.027 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf -F src/os_unix.c 1debf5ea6efd0f35335a2a615198a7a1017ffd4b +F src/os_unix.c 919972244dd7267815f9fc176b662390ff0b2348 F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -916,14 +916,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P def98fd23e42bda13547e38ab13fed0e6554ce99 -R 2ceb7e2495de2e32fa2e2aca83b58f09 +P 725708465072fc63736e99610cc9cb0ac336145a +R c6fd073182d6b083be2e4d503e5f99b8 U drh -Z e7ee1c18a6d623c4d19a0ae664dea8d8 +Z 981ae6e8a2633665045ed876d4741a1e -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNf7GDoxKgR168RlERAhc+AJ9qHfOaDlOtj2TqHpdpAXpIiMjRTwCeP6Tv -esEJjmOwgIx+D+pi9BcOh8Y= -=lte8 +iD8DBQFNf7lCoxKgR168RlERAhprAJkB1y4SWHLxKnmODUA6QMdw7pgj8wCgi+YB +9Q1erlHqYv/DtUPtH7mUHBE= +=2haN -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 72a3cfb274..4f297c4720 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -725708465072fc63736e99610cc9cb0ac336145a \ No newline at end of file +d9846834993079fb2e42d6bd2644b2154ef324d1 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 246a2d5776..f771efdad5 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -247,6 +247,7 @@ 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 */ /* ** Include code that is common to all os_*.c files @@ -1192,20 +1193,26 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ ** Attempt to set a system-lock on the file pFile. The lock is ** described by pLock. ** -** If the pFile was opened from unix-excl, then the only lock ever -** obtained is an exclusive lock, and it is obtained exactly once +** If the pFile was opened read/write from unix-excl, then the only lock +** ever obtained is an exclusive lock, and it is obtained exactly once ** the first time any lock is attempted. All subsequent system locking ** operations become no-ops. Locking operations still happen internally, ** in order to coordinate access between separate database connections ** within this process, but all of that is handled in memory and the ** operating system does not participate. +** +** This function is a pass-through to fcntl(F_SETLK) if pFile is using +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" +** and is read-only. */ static int unixFileLock(unixFile *pFile, struct flock *pLock){ int rc; unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); assert( pInode!=0 ); - if( (pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock ){ + if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) + && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) + ){ if( pInode->bProcessLock==0 ){ struct flock lock; assert( pInode->nLock==0 ); @@ -4402,7 +4409,8 @@ static int fillInUnixFile( sqlite3_file *pId, /* Write to the unixFile structure here */ const char *zFilename, /* Name of the file being opened */ int noLock, /* Omit locking if true */ - int isDelete /* Delete on close if true */ + int isDelete, /* Delete on close if true */ + int isReadOnly /* True if the file is opened read-only */ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; @@ -4435,6 +4443,9 @@ static int fillInUnixFile( }else{ pNew->ctrlFlags = 0; } + if( isReadOnly ){ + pNew->ctrlFlags |= UNIXFILE_RDONLY; + } #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); @@ -4942,6 +4953,7 @@ static int unixOpen( openFlags &= ~(O_RDWR|O_CREAT); flags |= SQLITE_OPEN_READONLY; openFlags |= O_RDONLY; + isReadonly = 1; fd = robust_open(zName, openFlags, openMode); } if( fd<0 ){ @@ -5038,7 +5050,8 @@ static int unixOpen( useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, + isDelete, isReadonly); if( rc==SQLITE_OK ){ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); if( rc!=SQLITE_OK ){ @@ -5055,7 +5068,8 @@ static int unixOpen( } #endif - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, + isDelete, isReadonly); open_finished: if( rc!=SQLITE_OK ){ sqlite3_free(p->pUnused); @@ -5717,7 +5731,7 @@ static int proxyCreateUnixFile( pUnused->flags = openFlags; pNew->pUnused = pUnused; - rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0); + rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0); if( rc==SQLITE_OK ){ *ppFile = pNew; return SQLITE_OK; From 97ae8ffb7aed820d7db6f94e7adff23b8a9c51a5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2011 16:56:29 +0000 Subject: [PATCH 30/35] Add the VFS-trace shim. FossilOrigin-Name: f49a9ef3387bd4453f5654ebe83fea445c03cf4d --- manifest | 19 +- manifest.uuid | 2 +- src/shell.c | 14 + src/test_vfstrace.c | 692 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 717 insertions(+), 10 deletions(-) create mode 100644 src/test_vfstrace.c diff --git a/manifest b/manifest index 3441c2202d..603d8e598e 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Make\sthe\s"unix-excl"\sVFS\swork\sexactly\slike\s"unix"\sif\sthe\sdatabase\nfile\sis\sread-only. -D 2011-03-15T19:08:48.027 +C Add\sthe\sVFS-trace\sshim. +D 2011-03-16T16:56:29.108 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 -F src/shell.c ea40658271dfff494dab3dee4a1c0f382d239675 +F src/shell.c 1378c13b8a58e55409cc5386545ffd552de929e3 F src/sqlite.h.in 369c767e6b9f101d63d8e4c5e40279f975ccec08 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 @@ -226,6 +226,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86 +F src/test_vfstrace.c 3fd3e07bcc78ba65eb0e90263dab83b6bf4a682d F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c 95d2ff4b2996fabe886c9764b5978980e29f4afa @@ -916,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 725708465072fc63736e99610cc9cb0ac336145a -R c6fd073182d6b083be2e4d503e5f99b8 +P d9846834993079fb2e42d6bd2644b2154ef324d1 +R 2013b1ad097a7d85c1ea307de0fd7493 U drh -Z 981ae6e8a2633665045ed876d4741a1e +Z 4add82de13b36ad23f5fa229ae2ae933 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNf7lCoxKgR168RlERAhprAJkB1y4SWHLxKnmODUA6QMdw7pgj8wCgi+YB -9Q1erlHqYv/DtUPtH7mUHBE= -=2haN +iD8DBQFNgOvAoxKgR168RlERAgnSAJ4ojV+ajE7GhQi3ztWXgDEl3wO4+ACeJUcm +bDZfksV2K6w+qpeNasjY+/Y= +=Kcyn -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 4f297c4720..8809f16c6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9846834993079fb2e42d6bd2644b2154ef324d1 \ No newline at end of file +f49a9ef3387bd4453f5654ebe83fea445c03cf4d \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 34e821ca3d..80811f81d7 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2638,6 +2638,7 @@ int main(int argc, char **argv){ int i; int rc = 0; + Argv0 = argv[0]; main_init(&data); stdin_is_interactive = isatty(0); @@ -2685,6 +2686,17 @@ int main(int argc, char **argv){ if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); +#endif +#ifdef SQLITE_ENABLE_VFSTRACE + }else if( strcmp(argv[i],"-vfstrace")==0 ){ + extern int vfstrace_register( + const char *zTraceName, + const char *zOldVfsName, + int (*xOut)(const char*,void*), + void *pOutArg, + int makeDefault + ); + vfstrace_register("trace",0,(int(*)(const char*,void*))fputs, stderr, 1); #endif }else if( strcmp(argv[i],"-vfs")==0 ){ sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]); @@ -2804,6 +2816,8 @@ int main(int argc, char **argv){ i++; }else if( strcmp(z,"-vfs")==0 ){ i++; + }else if( strcmp(z,"-vfstrace")==0 ){ + i++; }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){ usage(1); }else{ diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c new file mode 100644 index 0000000000..c8325eddf7 --- /dev/null +++ b/src/test_vfstrace.c @@ -0,0 +1,692 @@ +/* +** 2011 March 16 +** +** 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 code implements a VFS shim that writes diagnostic +** output for each VFS call, similar to "strace". +*/ +#include +#include +#include "sqlite3.h" + +/* +** An instance of this structure is attached to the each trace VFS to +** provide auxiliary information. +*/ +typedef struct vfstrace_info vfstrace_info; +struct vfstrace_info { + sqlite3_vfs *pRootVfs; /* The underlying real VFS */ + int (*xOut)(const char*, void*); /* Send output here */ + void *pOutArg; /* First argument to xOut */ + const char *zVfsName; /* Name of this trace-VFS */ + sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */ +}; + +/* +** The sqlite3_file object for the trace VFS +*/ +typedef struct vfstrace_file vfstrace_file; +struct vfstrace_file { + sqlite3_file base; /* Base class. Must be first */ + vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */ + const char *zFName; /* Base name of the file */ + sqlite3_file *pReal; /* The real underlying file */ +}; + +/* +** Method declarations for vfstrace_file. +*/ +static int vfstraceClose(sqlite3_file*); +static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64); +static int vfstraceTruncate(sqlite3_file*, sqlite3_int64 size); +static int vfstraceSync(sqlite3_file*, int flags); +static int vfstraceFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int vfstraceLock(sqlite3_file*, int); +static int vfstraceUnlock(sqlite3_file*, int); +static int vfstraceCheckReservedLock(sqlite3_file*, int *); +static int vfstraceFileControl(sqlite3_file*, int op, void *pArg); +static int vfstraceSectorSize(sqlite3_file*); +static int vfstraceDeviceCharacteristics(sqlite3_file*); +static int vfstraceShmLock(sqlite3_file*,int,int,int); +static int vfstraceShmMap(sqlite3_file*,int,int,int, void volatile **); +static void vfstraceShmBarrier(sqlite3_file*); +static int vfstraceShmUnmap(sqlite3_file*,int); + +/* +** Method declarations for vfstrace_vfs. +*/ +static int vfstraceOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int vfstraceDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int vfstraceAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int vfstraceFullPathname(sqlite3_vfs*, const char *zName, int, char *); +static void *vfstraceDlOpen(sqlite3_vfs*, const char *zFilename); +static void vfstraceDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*vfstraceDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); +static void vfstraceDlClose(sqlite3_vfs*, void*); +static int vfstraceRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int vfstraceSleep(sqlite3_vfs*, int microseconds); +static int vfstraceCurrentTime(sqlite3_vfs*, double*); +static int vfstraceGetLastError(sqlite3_vfs*, int, char*); +static int vfstraceCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); +static int vfstraceSetSystemCall(sqlite3_vfs*, const char *zName, void *pFunc); +static void *vfstraceGetSystemCall(sqlite3_vfs*, const char *zName); +static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName); + +/* +** Return a pointer to the tail of the pathname. Examples: +** +** /home/drh/xyzzy.txt -> xyzzy.txt +** xyzzy.txt -> xyzzy.txt +*/ +static const char *fileTail(const char *z){ + int i; + if( z==0 ) return 0; + i = strlen(z)-1; + while( i>0 && z[i-1]!='/' ){ i--; } + return &z[i]; +} + +/* +** Send trace output defined by zFormat and subsequent arguments. +*/ +static void vfstrace_printf( + vfstrace_info *pInfo, + const char *zFormat, + ... +){ + va_list ap; + char *zMsg; + va_start(ap, zFormat); + zMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + pInfo->xOut(zMsg, pInfo->pOutArg); + sqlite3_free(zMsg); +} + +/* +** Convert value rc into a string and print it using zFormat. zFormat +** should have exactly one %s +*/ +static void vfstrace_print_errcode( + vfstrace_info *pInfo, + const char *zFormat, + int rc +){ + char zBuf[50]; + char *zVal; + switch( rc ){ + case SQLITE_OK: zVal = "SQLITE_OK"; break; + case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break; + case SQLITE_PERM: zVal = "SQLITE_PERM"; break; + case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break; + case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break; + case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break; + case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break; + case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break; + case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break; + case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break; + case SQLITE_FULL: zVal = "SQLITE_FULL"; break; + case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break; + case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break; + case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break; + case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break; + case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break; + case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break; + case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break; + case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break; + case SQLITE_IOERR_READ: zVal = "SQLITE_IOERR_READ"; break; + case SQLITE_IOERR_SHORT_READ: zVal = "SQLITE_IOERR_SHORT_READ"; break; + case SQLITE_IOERR_WRITE: zVal = "SQLITE_IOERR_WRITE"; break; + case SQLITE_IOERR_FSYNC: zVal = "SQLITE_IOERR_FSYNC"; break; + case SQLITE_IOERR_DIR_FSYNC: zVal = "SQLITE_IOERR_DIR_FSYNC"; break; + case SQLITE_IOERR_TRUNCATE: zVal = "SQLITE_IOERR_TRUNCATE"; break; + case SQLITE_IOERR_FSTAT: zVal = "SQLITE_IOERR_FSTAT"; break; + case SQLITE_IOERR_UNLOCK: zVal = "SQLITE_IOERR_UNLOCK"; break; + case SQLITE_IOERR_RDLOCK: zVal = "SQLITE_IOERR_RDLOCK"; break; + case SQLITE_IOERR_DELETE: zVal = "SQLITE_IOERR_DELETE"; break; + case SQLITE_IOERR_BLOCKED: zVal = "SQLITE_IOERR_BLOCKED"; break; + case SQLITE_IOERR_NOMEM: zVal = "SQLITE_IOERR_NOMEM"; break; + case SQLITE_IOERR_ACCESS: zVal = "SQLITE_IOERR_ACCESS"; break; + case SQLITE_IOERR_CHECKRESERVEDLOCK: + zVal = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; + case SQLITE_IOERR_LOCK: zVal = "SQLITE_IOERR_LOCK"; break; + case SQLITE_IOERR_CLOSE: zVal = "SQLITE_IOERR_CLOSE"; break; + case SQLITE_IOERR_DIR_CLOSE: zVal = "SQLITE_IOERR_DIR_CLOSE"; break; + case SQLITE_IOERR_SHMOPEN: zVal = "SQLITE_IOERR_SHMOPEN"; break; + case SQLITE_IOERR_SHMSIZE: zVal = "SQLITE_IOERR_SHMSIZE"; break; + case SQLITE_IOERR_SHMLOCK: zVal = "SQLITE_IOERR_SHMLOCK"; break; + case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break; + case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break; + case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break; + default: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc); + zVal = zBuf; + break; + } + } + vfstrace_printf(pInfo, zFormat, zVal); +} + +/* +** Close an vfstrace-file. +*/ +static int vfstraceClose(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xClose(p->pReal); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + if( rc==SQLITE_OK ){ + sqlite3_free((void*)p->base.pMethods); + p->base.pMethods = 0; + } + return rc; +} + +/* +** Read data from an vfstrace-file. +*/ +static int vfstraceRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xRead(%s,*,%d,%lld)", pInfo->zVfsName, p->zFName, + iAmt, iOfst); + rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Write data to an vfstrace-file. +*/ +static int vfstraceWrite( + sqlite3_file *pFile, + const void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xWrite(%s,*,%d,%lld)", pInfo->zVfsName, p->zFName, + iAmt, iOfst); + rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Truncate an vfstrace-file. +*/ +static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName, + size); + rc = p->pReal->pMethods->xTruncate(p->pReal, size); + vfstrace_printf(pInfo, " -> %d\n", rc); + return rc; +} + +/* +** Sync an vfstrace-file. +*/ +static int vfstraceSync(sqlite3_file *pFile, int flags){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xSync(%s,%d)", pInfo->zVfsName, p->zFName, flags); + rc = p->pReal->pMethods->xSync(p->pReal, flags); + vfstrace_printf(pInfo, " -> %d\n", rc); + return rc; +} + +/* +** Return the current file-size of an vfstrace-file. +*/ +static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); + vfstrace_print_errcode(pInfo, " -> %s,", rc); + vfstrace_printf(pInfo, " size=%lld\n", *pSize); + return rc; +} + +/* +** Lock an vfstrace-file. +*/ +static int vfstraceLock(sqlite3_file *pFile, int eLock){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xLock(%s,%d)", pInfo->zVfsName, p->zFName, eLock); + rc = p->pReal->pMethods->xLock(p->pReal, eLock); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Unlock an vfstrace-file. +*/ +static int vfstraceUnlock(sqlite3_file *pFile, int eLock){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xUnlock(%s,%d)", pInfo->zVfsName, p->zFName,eLock); + rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Check if another file-handle holds a RESERVED lock on an vfstrace-file. +*/ +static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)", + pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", out=%d\n", *pResOut); + return rc; +} + +/* +** File control method. For custom operations on an vfstrace-file. +*/ +static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xFileControl(%s,op=%d)", + pInfo->zVfsName, p->zFName, op); + rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Return the sector-size in bytes for an vfstrace-file. +*/ +static int vfstraceSectorSize(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xSectorSize(p->pReal); + vfstrace_printf(pInfo, " -> %d\n", rc); + return rc; +} + +/* +** Return the device characteristic flags supported by an vfstrace-file. +*/ +static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)", + pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal); + vfstrace_printf(pInfo, " -> 0x%08x\n", rc); + return rc; +} + +/* +** Shared-memory operations. +*/ +static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,flags=%d)", + pInfo->zVfsName, p->zFName, ofst, n, flags); + rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static int vfstraceShmMap( + sqlite3_file *pFile, + int iRegion, + int szRegion, + int isWrite, + void volatile **pp +){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)", + pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite); + rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static void vfstraceShmBarrier(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName); + p->pReal->pMethods->xShmBarrier(p->pReal); +} +static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)", + pInfo->zVfsName, p->zFName, delFlag); + rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + + + +/* +** Open an vfstrace file handle. +*/ +static int vfstraceOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFile, + int flags, + int *pOutFlags +){ + int rc; + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + p->pInfo = pInfo; + p->zFName = fileTail(zName); + p->pReal = (sqlite3_file *)&p[1]; + rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags); + vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)", + pInfo->zVfsName, p->zFName, flags); + if( p->pReal->pMethods ){ + sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) ); + const sqlite3_io_methods *pSub = p->pReal->pMethods; + memset(pNew, 0, sizeof(*pNew)); + pNew->iVersion = pSub->iVersion; + pNew->xClose = vfstraceClose; + pNew->xRead = vfstraceRead; + pNew->xWrite = vfstraceWrite; + pNew->xTruncate = vfstraceTruncate; + pNew->xSync = vfstraceSync; + pNew->xFileSize = vfstraceFileSize; + pNew->xLock = vfstraceLock; + pNew->xUnlock = vfstraceUnlock; + pNew->xCheckReservedLock = vfstraceCheckReservedLock; + pNew->xFileControl = vfstraceFileControl; + pNew->xSectorSize = vfstraceSectorSize; + pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics; + if( pNew->iVersion>=2 ){ + pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0; + pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0; + pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0; + pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0; + } + pFile->pMethods = pNew; + } + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags); + return rc; +} + +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)", + pInfo->zVfsName, zPath, dirSync); + rc = pRoot->xDelete(pRoot, zPath, dirSync); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +*/ +static int vfstraceAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)", + pInfo->zVfsName, zPath, flags); + rc = pRoot->xAccess(pRoot, zPath, flags, pResOut); + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", out=%d\n", *pResOut); + return rc; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (DEVSYM_MAX_PATHNAME+1) bytes. +*/ +static int vfstraceFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")", + pInfo->zVfsName, zPath); + rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut); + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut); + return rc; +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath); + return pRoot->xDlOpen(pRoot, zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte); + pRoot->xDlError(pRoot, nByte, zErrMsg); + vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstrace_printf(pInfo, "%s.xDlSym(\"%s\")\n", pInfo->zVfsName, zSym); + return pRoot->xDlSym(pRoot, p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName); + pRoot->xDlClose(pRoot, pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte); + return pRoot->xRandomness(pRoot, nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xSleep(pRoot, nMicro); +} + +/* +** Return the current time as a Julian Day number in *pTimeOut. +*/ +static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xCurrentTime(pRoot, pTimeOut); +} +static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xCurrentTimeInt64(pRoot, pTimeOut); +} + +/* +** Return th3 emost recent error code and message +*/ +static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xGetLastError(pRoot, iErr, zErr); +} + +/* +** Override system calls. +*/ +static int vfstraceSetSystemCall( + sqlite3_vfs *pVfs, + const char *zName, + void *pFunc +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xSetSystemCall(pRoot, zName, pFunc); +} +static void *vfstraceGetSystemCall(sqlite3_vfs *pVfs, const char *zName){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xGetSystemCall(pRoot, zName); +} +static const char *vfstraceNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xNextSystemCall(pRoot, zName); +} + + +/* +** Clients invoke this routine to construct a new trace-vfs shim. +** +** Return SQLITE_OK on success. +** +** SQLITE_NOMEM is returned in the case of a memory allocation error. +** SQLITE_NOTFOUND is returned if zOldVfsName does not exist. +*/ +int vfstrace_register( + const char *zTraceName, /* Name of the newly constructed VFS */ + const char *zOldVfsName, /* Name of the underlying VFS */ + int (*xOut)(const char*,void*), /* Output routine. ex: fputs */ + void *pOutArg, /* 2nd argument to xOut. ex: stderr */ + int makeDefault /* True to make the new VFS the default */ +){ + sqlite3_vfs *pNew; + sqlite3_vfs *pRoot; + vfstrace_info *pInfo; + int nName; + int nByte; + + pRoot = sqlite3_vfs_find(zOldVfsName); + if( pRoot==0 ) return SQLITE_NOTFOUND; + nName = strlen(zTraceName); + nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1; + pNew = sqlite3_malloc( nByte ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, nByte); + pInfo = (vfstrace_info*)&pNew[1]; + pNew->iVersion = pRoot->iVersion; + pNew->szOsFile = pRoot->szOsFile + sizeof(vfstrace_file); + pNew->mxPathname = pRoot->mxPathname; + pNew->zName = (char*)&pInfo[1]; + memcpy((char*)&pInfo[1], zTraceName, nName+1); + pNew->pAppData = pInfo; + pNew->xOpen = vfstraceOpen; + pNew->xDelete = vfstraceDelete; + pNew->xAccess = vfstraceAccess; + pNew->xFullPathname = vfstraceFullPathname; + pNew->xDlOpen = pRoot->xDlOpen==0 ? 0 : vfstraceDlOpen; + pNew->xDlError = pRoot->xDlError==0 ? 0 : vfstraceDlError; + pNew->xDlSym = pRoot->xDlSym==0 ? 0 : vfstraceDlSym; + pNew->xDlClose = pRoot->xDlClose==0 ? 0 : vfstraceDlClose; + pNew->xRandomness = vfstraceRandomness; + pNew->xSleep = vfstraceSleep; + pNew->xCurrentTime = vfstraceCurrentTime; + pNew->xGetLastError = pRoot->xGetLastError==0 ? 0 : vfstraceGetLastError; + if( pNew->iVersion>=2 ){ + pNew->xCurrentTimeInt64 = pRoot->xCurrentTimeInt64==0 ? 0 : + vfstraceCurrentTimeInt64; + if( pNew->iVersion>=3 ){ + pNew->xSetSystemCall = pRoot->xSetSystemCall==0 ? 0 : + vfstraceSetSystemCall; + pNew->xGetSystemCall = pRoot->xGetSystemCall==0 ? 0 : + vfstraceGetSystemCall; + pNew->xNextSystemCall = pRoot->xNextSystemCall==0 ? 0 : + vfstraceNextSystemCall; + } + } + pInfo->pRootVfs = pRoot; + pInfo->xOut = xOut; + pInfo->pOutArg = pOutArg; + pInfo->zVfsName = pNew->zName; + pInfo->pTraceVfs = pNew; + vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n", + pInfo->zVfsName, pRoot->zName); + return sqlite3_vfs_register(pNew, makeDefault); +} From 2b625e243e0b61b855d0551fef1b1b457d634cf4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2011 17:05:28 +0000 Subject: [PATCH 31/35] Add the -vfstrace option to the usage error message in the shell. FossilOrigin-Name: baca45c549e1c144257ee657258939640120e094 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/shell.c | 6 ++++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 603d8e598e..ac9a29b955 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\sthe\sVFS-trace\sshim. -D 2011-03-16T16:56:29.108 +C Add\sthe\s-vfstrace\soption\sto\sthe\susage\serror\smessage\sin\sthe\sshell. +D 2011-03-16T17:05:28.564 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 -F src/shell.c 1378c13b8a58e55409cc5386545ffd552de929e3 +F src/shell.c 75ec746b9661e9b5cf956ef4cd9833c0545ef037 F src/sqlite.h.in 369c767e6b9f101d63d8e4c5e40279f975ccec08 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 @@ -917,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d9846834993079fb2e42d6bd2644b2154ef324d1 -R 2013b1ad097a7d85c1ea307de0fd7493 +P f49a9ef3387bd4453f5654ebe83fea445c03cf4d +R 10a20ce6ae78a895cdea10598348f18e U drh -Z 4add82de13b36ad23f5fa229ae2ae933 +Z acc5d93678df1d134e86d0d878bc7d5a -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNgOvAoxKgR168RlERAgnSAJ4ojV+ajE7GhQi3ztWXgDEl3wO4+ACeJUcm -bDZfksV2K6w+qpeNasjY+/Y= -=Kcyn +iD8DBQFNgO3boxKgR168RlERAjamAJ4kL/kDftJ0EQwueulbIUjVkAOzEQCfRxty +gHYZrl1EnYTdUM+hmPqP9As= +=p45y -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 8809f16c6c..d43b11e4c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f49a9ef3387bd4453f5654ebe83fea445c03cf4d \ No newline at end of file +baca45c549e1c144257ee657258939640120e094 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 80811f81d7..9d51aa95dc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2602,6 +2602,9 @@ static const char zOptions[] = " -nullvalue 'text' set text string for NULL values\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" +#ifdef SQLITE_ENABLE_VFSTRACE + " -vfstrace enable tracing of all VFS calls\n" +#endif ; static void usage(int showDetail){ fprintf(stderr, @@ -2638,7 +2641,6 @@ int main(int argc, char **argv){ int i; int rc = 0; - Argv0 = argv[0]; main_init(&data); stdin_is_interactive = isatty(0); @@ -2696,7 +2698,7 @@ int main(int argc, char **argv){ void *pOutArg, int makeDefault ); - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs, stderr, 1); + vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); #endif }else if( strcmp(argv[i],"-vfs")==0 ){ sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]); From 2f8ebdde3ef30b13fc00913bd634181156e20604 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2011 18:54:23 +0000 Subject: [PATCH 32/35] Additional interpretation of flags and constants in the VFS trace output. FossilOrigin-Name: 3e984195f1f6d28734456dd726d226cedf207da2 --- manifest | 18 ++++---- manifest.uuid | 2 +- src/test_vfstrace.c | 104 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index ac9a29b955..ceed9e597f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\sthe\s-vfstrace\soption\sto\sthe\susage\serror\smessage\sin\sthe\sshell. -D 2011-03-16T17:05:28.564 +C Additional\sinterpretation\sof\sflags\sand\sconstants\sin\sthe\sVFS\strace\soutput. +D 2011-03-16T18:54:23.037 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -226,7 +226,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86 -F src/test_vfstrace.c 3fd3e07bcc78ba65eb0e90263dab83b6bf4a682d +F src/test_vfstrace.c f5c3b3b893d81a580d0f577e6d9bcfc1fd496136 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c 95d2ff4b2996fabe886c9764b5978980e29f4afa @@ -917,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f49a9ef3387bd4453f5654ebe83fea445c03cf4d -R 10a20ce6ae78a895cdea10598348f18e +P baca45c549e1c144257ee657258939640120e094 +R ce715121c7ed754dc718fb1bfe515a2f U drh -Z acc5d93678df1d134e86d0d878bc7d5a +Z 63d44dd1d9cda650862ed5c1ffde651b -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNgO3boxKgR168RlERAjamAJ4kL/kDftJ0EQwueulbIUjVkAOzEQCfRxty -gHYZrl1EnYTdUM+hmPqP9As= -=p45y +iD8DBQFNgQdioxKgR168RlERAjrWAJ0csO53SVkhS4LgdWU2TMBY3h2/owCfSmfo +JE1tPjv0O+bB3lGc+tkEKvk= +=czhw -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index d43b11e4c4..97ddfe5e79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -baca45c549e1c144257ee657258939640120e094 \ No newline at end of file +3e984195f1f6d28734456dd726d226cedf207da2 \ No newline at end of file diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c index c8325eddf7..24bd0afaee 100644 --- a/src/test_vfstrace.c +++ b/src/test_vfstrace.c @@ -176,6 +176,16 @@ static void vfstrace_print_errcode( vfstrace_printf(pInfo, zFormat, zVal); } +/* +** Append to a buffer. +*/ +static void strappend(char *z, int *pI, const char *zAppend){ + int i = *pI; + while( zAppend[0] ){ z[i++] = *(zAppend++); } + z[i] = 0; + *pI = i; +} + /* ** Close an vfstrace-file. */ @@ -205,8 +215,8 @@ static int vfstraceRead( vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xRead(%s,*,%d,%lld)", pInfo->zVfsName, p->zFName, - iAmt, iOfst); + vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)", + pInfo->zVfsName, p->zFName, iAmt, iOfst); rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; @@ -224,8 +234,8 @@ static int vfstraceWrite( vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xWrite(%s,*,%d,%lld)", pInfo->zVfsName, p->zFName, - iAmt, iOfst); + vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)", + pInfo->zVfsName, p->zFName, iAmt, iOfst); rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; @@ -252,7 +262,18 @@ static int vfstraceSync(sqlite3_file *pFile, int flags){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xSync(%s,%d)", pInfo->zVfsName, p->zFName, flags); + int i; + char zBuf[100]; + memcpy(zBuf, "|0", 3); + i = 0; + if( flags & SQLITE_SYNC_FULL ) strappend(zBuf, &i, "|FULL"); + else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL"); + if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY"); + if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){ + sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags); + } + vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName, + &zBuf[1]); rc = p->pReal->pMethods->xSync(p->pReal, flags); vfstrace_printf(pInfo, " -> %d\n", rc); return rc; @@ -272,6 +293,20 @@ static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ return rc; } +/* +** Return the name of a lock. +*/ +static const char *lockName(int eLock){ + const char *azLockNames[] = { + "NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE" + }; + if( eLock<0 || eLock>=sizeof(azLockNames)/sizeof(azLockNames[0]) ){ + return "???"; + }else{ + return azLockNames[eLock]; + } +} + /* ** Lock an vfstrace-file. */ @@ -279,7 +314,8 @@ static int vfstraceLock(sqlite3_file *pFile, int eLock){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xLock(%s,%d)", pInfo->zVfsName, p->zFName, eLock); + vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName, + lockName(eLock)); rc = p->pReal->pMethods->xLock(p->pReal, eLock); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; @@ -292,7 +328,8 @@ static int vfstraceUnlock(sqlite3_file *pFile, int eLock){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xUnlock(%s,%d)", pInfo->zVfsName, p->zFName,eLock); + vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName, + lockName(eLock)); rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; @@ -320,8 +357,35 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xFileControl(%s,op=%d)", - pInfo->zVfsName, p->zFName, op); + char zBuf[100]; + char *zOp; + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break; + case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break; + case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break; + case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break; + case SQLITE_FCNTL_SIZE_HINT: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld", + *(sqlite3_int64*)pArg); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; + case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break; + case 0xca093fa0: zOp = "DB_UNCHANGED"; break; + default: { + sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); + zOp = zBuf; + break; + } + } + vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)", + pInfo->zVfsName, p->zFName, zOp); rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; @@ -361,8 +425,18 @@ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; - vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,flags=%d)", - pInfo->zVfsName, p->zFName, ofst, n, flags); + char zLck[100]; + int i = 0; + memcpy(zLck, "|0", 3); + if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK"); + if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK"); + if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED"); + if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE"); + if( flags & ~(0xf) ){ + sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags); + } + vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)", + pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]); rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; @@ -417,7 +491,7 @@ static int vfstraceOpen( vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; p->pInfo = pInfo; - p->zFName = fileTail(zName); + p->zFName = zName ? fileTail(zName) : ""; p->pReal = (sqlite3_file *)&p[1]; rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags); vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)", @@ -448,7 +522,11 @@ static int vfstraceOpen( pFile->pMethods = pNew; } vfstrace_print_errcode(pInfo, " -> %s", rc); - vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags); + if( pOutFlags ){ + vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags); + }else{ + vfstrace_printf(pInfo, "\n"); + } return rc; } From 1f9c7663ce09be70beb0259fa2c71c165cab4325 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2011 01:34:26 +0000 Subject: [PATCH 33/35] Enhances to the query planner such that "x IS NULL" constraints take the STAT2 statistics into account, just like "x=VALUE" constraints. FossilOrigin-Name: 2353176811f752a16c1f2351a3d3431919b062a9 --- install-sh | 0 manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/where.c | 12 +++++++++--- test/analyze5.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ test/progress.test | 0 tool/mkopts.tcl | 0 7 files changed, 68 insertions(+), 17 deletions(-) mode change 100644 => 100755 install-sh mode change 100755 => 100644 test/progress.test mode change 100755 => 100644 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100644 new mode 100755 diff --git a/manifest b/manifest index ceed9e597f..b04b624d6b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Additional\sinterpretation\sof\sflags\sand\sconstants\sin\sthe\sVFS\strace\soutput. -D 2011-03-16T18:54:23.037 +C Enhances\sto\sthe\squery\splanner\ssuch\sthat\s"x\sIS\sNULL"\sconstraints\stake\sthe\nSTAT2\sstatistics\sinto\saccount,\sjust\slike\s"x=VALUE"\sconstraints. +D 2011-03-17T01:34:26.570 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk 54190fab7cdba523e311c274c95ea480f32abfb5 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -246,7 +246,7 @@ F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 27c2f4e249213faeab548f628e52c005623f195d +F src/where.c a41a1c64aceb4138a865e6dc939f781f53401d68 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125 @@ -259,7 +259,7 @@ F test/analyze.test c1eb87067fc16ece7c07e823d6395fd831b270c5 F test/analyze2.test 8f2b1534d43f5547ce9a6b736c021d4192c75be3 F test/analyze3.test d61f55d8b472fc6e713160b1e577f7a68e63f38b F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 -F test/analyze5.test 0618d2fe8982a5dae1d4e92152acc8ecbaf52be2 +F test/analyze5.test adc89b92fc9fee5ca1cb0bc8512f3206ad0fe5aa F test/analyze6.test 1ba1aea8fad25a77ffd71f24522d1bb9ecc949fc F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3 F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6 @@ -605,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -892,7 +892,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -917,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P baca45c549e1c144257ee657258939640120e094 -R ce715121c7ed754dc718fb1bfe515a2f +P 3e984195f1f6d28734456dd726d226cedf207da2 +R 291ccee36a06fddbdbf66dee9d0c5dc8 U drh -Z 63d44dd1d9cda650862ed5c1ffde651b +Z 44243678e5ac002f859d95b6693267ff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNgQdioxKgR168RlERAjrWAJ0csO53SVkhS4LgdWU2TMBY3h2/owCfSmfo -JE1tPjv0O+bB3lGc+tkEKvk= -=czhw +iD8DBQFNgWUmoxKgR168RlERArUBAJ9O6MIvLSm72rE66pJVBmPTs+4oyACdHack +G7nsgBYo5KQjyDA5i3CGse8= +=owlC -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 97ddfe5e79..86fa92432e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e984195f1f6d28734456dd726d226cedf207da2 \ No newline at end of file +2353176811f752a16c1f2351a3d3431919b062a9 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 2b89055251..0cda03f451 100644 --- a/src/where.c +++ b/src/where.c @@ -2545,8 +2545,12 @@ int whereEqualScanEst( assert( p->aSample!=0 ); aff = p->pTable->aCol[p->aiColumn[0]].affinity; - rc = valueFromExpr(pParse, pExpr, aff, &pRhs); - if( rc ) goto whereEqualScanEst_cancel; + if( pExpr ){ + rc = valueFromExpr(pParse, pExpr, aff, &pRhs); + if( rc ) goto whereEqualScanEst_cancel; + }else{ + pRhs = sqlite3ValueNew(pParse->db); + } if( pRhs==0 ) return SQLITE_NOTFOUND; rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower); if( rc ) goto whereEqualScanEst_cancel; @@ -2935,7 +2939,9 @@ static void bestBtreeIndex( ** VALUE and how common that value is according to the histogram. */ if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 ){ - if( pFirstTerm->eOperator==WO_EQ ){ + if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ + testcase( pFirstTerm->eOperator==WO_EQ ); + testcase( pFirstTerm->pOperator==WO_ISNULL ); whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow); }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){ whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); diff --git a/test/analyze5.test b/test/analyze5.test index e08893a180..224433b7df 100644 --- a/test/analyze5.test +++ b/test/analyze5.test @@ -164,6 +164,8 @@ foreach {testid where index rows} { 301 {y=1} t1y 50 302 {y=0.1} t1y 50 + 400 {x IS NULL} t1x 400 + } { # Verify that the expected index is used with the expected row count do_test analyze5-1.${testid}a { @@ -190,5 +192,48 @@ foreach {testid where index rows} { } {ok} } +# Increase the number of NULLs in column x +# +db eval { + UPDATE t1 SET x=NULL; + UPDATE t1 SET x=rowid + WHERE rowid IN (SELECT rowid FROM t1 ORDER BY random() LIMIT 5); + ANALYZE; +} + +# Verify that range queries generate the correct row count estimates +# +foreach {testid where index rows} { + 500 {x IS NULL AND u='charlie'} t1u 20 + 501 {x=1 AND u='charlie'} t1x 5 + 502 {x IS NULL} {} 100 + 503 {x=1} t1x 50 + 504 {x IS NOT NULL} t1x 25 + +} { + # Verify that the expected index is used with the expected row count + do_test analyze5-1.${testid}a { + set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] + set idx {} + regexp {INDEX (t1.) } $x all idx + regexp {~([0-9]+) rows} $x all nrow + list $idx $nrow + } [list $index $rows] + + # Verify that the same result is achieved regardless of whether or not + # the index is used + do_test analyze5-1.${testid}b { + set w2 [string map {y +y z +z} $where] + set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\ + ORDER BY +rowid"] + set a2 [db eval "SELECT rowid FROM t1 WHERE $where ORDER BY +rowid"] + if {$a1==$a2} { + set res ok + } else { + set res "a1=\[$a1\] a2=\[$a2\]" + } + set res + } {ok} +} finish_test diff --git a/test/progress.test b/test/progress.test old mode 100755 new mode 100644 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100755 new mode 100644 From ac8eb11375458631836e42f43164e88c3f569df5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2011 01:58:21 +0000 Subject: [PATCH 34/35] Comment enhancement to better explain the logic in the "x IS NULL" optimization. FossilOrigin-Name: 869f894798a65f8bc0e0b083866a784fa0189f68 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/where.c | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b04b624d6b..a9110cb28d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Enhances\sto\sthe\squery\splanner\ssuch\sthat\s"x\sIS\sNULL"\sconstraints\stake\sthe\nSTAT2\sstatistics\sinto\saccount,\sjust\slike\s"x=VALUE"\sconstraints. -D 2011-03-17T01:34:26.570 +C Comment\senhancement\sto\sbetter\sexplain\sthe\slogic\sin\sthe\s"x\sIS\sNULL"\s\noptimization. +D 2011-03-17T01:58:21.662 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -246,7 +246,7 @@ F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c a41a1c64aceb4138a865e6dc939f781f53401d68 +F src/where.c a6e89fe7e56ab7e633be6fdebdddd857e9e5bc99 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125 @@ -917,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3e984195f1f6d28734456dd726d226cedf207da2 -R 291ccee36a06fddbdbf66dee9d0c5dc8 +P 2353176811f752a16c1f2351a3d3431919b062a9 +R ceaf122e76347e0b045461abe9cbfd0f U drh -Z 44243678e5ac002f859d95b6693267ff +Z 6e216a7f32c457388fcc438c6cd929ce -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNgWUmoxKgR168RlERArUBAJ9O6MIvLSm72rE66pJVBmPTs+4oyACdHack -G7nsgBYo5KQjyDA5i3CGse8= -=owlC +iD8DBQFNgWrBoxKgR168RlERAg4rAJ0ZbgbEbrWUz8iIL7EI7v8AcMLRpQCfZka3 +v7cQP/zk4VcNw9IakEHnWtw= +=fknb -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 86fa92432e..9f597732d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2353176811f752a16c1f2351a3d3431919b062a9 \ No newline at end of file +869f894798a65f8bc0e0b083866a784fa0189f68 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 0cda03f451..cdcaa98c01 100644 --- a/src/where.c +++ b/src/where.c @@ -2520,7 +2520,8 @@ range_est_fallback: ** an equality constraint x=VALUE and where that VALUE occurs in ** the histogram data. This only works when x is the left-most ** column of an index and sqlite_stat2 histogram data is available -** for that index. +** for that index. When pExpr==NULL that means the constraint is +** "x IS NULL" instead of "x=VALUE". ** ** Write the estimated row count into *pnRow and return SQLITE_OK. ** If unable to make an estimate, leave *pnRow unchanged and return From d416fe799569ff1a570009187d218e5d0dc7c86c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2011 16:45:50 +0000 Subject: [PATCH 35/35] Update the implementation of ".testctrl" in the command-line shell to use a look-up table rather than a long sequence of if-elses. Shorten source code lines of shell.c to 80 characters or less. FossilOrigin-Name: 54bacb95dd6e2d6ac4971391a40484ccb9126d29 --- manifest | 18 ++++++------ manifest.uuid | 2 +- src/shell.c | 77 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index a9110cb28d..13539c3ab4 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Comment\senhancement\sto\sbetter\sexplain\sthe\slogic\sin\sthe\s"x\sIS\sNULL"\s\noptimization. -D 2011-03-17T01:58:21.662 +C Update\sthe\simplementation\sof\s".testctrl"\sin\sthe\scommand-line\sshell\sto\suse\na\slook-up\stable\srather\sthan\sa\slong\ssequence\sof\sif-elses.\s\sShorten\ssource\ncode\slines\sof\sshell.c\sto\s80\scharacters\sor\sless. +D 2011-03-17T16:45:50.769 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 -F src/shell.c 75ec746b9661e9b5cf956ef4cd9833c0545ef037 +F src/shell.c 4a5e0ad845475c84881f0b25b1abba2ddaab0a72 F src/sqlite.h.in 369c767e6b9f101d63d8e4c5e40279f975ccec08 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 2cea3e47997e3f4d9b4f1ce62f99c35be1b5a586 @@ -917,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2353176811f752a16c1f2351a3d3431919b062a9 -R ceaf122e76347e0b045461abe9cbfd0f +P 869f894798a65f8bc0e0b083866a784fa0189f68 +R a8def7fc552253bddf0337de8f57667b U drh -Z 6e216a7f32c457388fcc438c6cd929ce +Z f32baca0676f04528da8db7e35d99aa0 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNgWrBoxKgR168RlERAg4rAJ0ZbgbEbrWUz8iIL7EI7v8AcMLRpQCfZka3 -v7cQP/zk4VcNw9IakEHnWtw= -=fknb +iD8DBQFNgjx3oxKgR168RlERAkZlAJ9g0EAzYOwFcF/NGcxGCGlF65eaGACfcZkt +bA9BP3Fet3XmbiRxAgQtxR0= +=Yzeg -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 9f597732d4..4be64fc574 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -869f894798a65f8bc0e0b083866a784fa0189f68 \ No newline at end of file +54bacb95dd6e2d6ac4971391a40484ccb9126d29 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9d51aa95dc..7eed290918 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2173,29 +2173,45 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ + static const struct { + const char *zCtrlName; /* Name of a test-control option */ + int ctrlCode; /* Integer code for that option */ + } aCtrl[] = { + { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, + { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, + { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, + { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, + { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, + { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, + { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, + { "assert", SQLITE_TESTCTRL_ASSERT }, + { "always", SQLITE_TESTCTRL_ALWAYS }, + { "reserve", SQLITE_TESTCTRL_RESERVE }, + { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, + { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, + { "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ }, + { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, + }; int testctrl = -1; int rc = 0; + int i, n; open_db(p); - /* convert testctrl text option to value. allow only the first - ** three characters of the option to be used or the numerical - ** value. */ - if( strncmp( azArg[1], "prng_save", 6 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_SAVE; - else if( strncmp( azArg[1], "prng_restore", 10 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_RESTORE; - else if( strncmp( azArg[1], "prng_reset", 10 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_RESET; - else if( strncmp( azArg[1], "bitvec_test", 6 )==3 ) testctrl = SQLITE_TESTCTRL_BITVEC_TEST; - else if( strncmp( azArg[1], "fault_install", 6 )==3 ) testctrl = SQLITE_TESTCTRL_FAULT_INSTALL; - else if( strncmp( azArg[1], "benign_malloc_hooks", 3 )==0 ) testctrl = SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS; - else if( strncmp( azArg[1], "pending_byte", 3 )==0 ) testctrl = SQLITE_TESTCTRL_PENDING_BYTE; - else if( strncmp( azArg[1], "assert", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ASSERT; - else if( strncmp( azArg[1], "always", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ALWAYS; - else if( strncmp( azArg[1], "reserve", 3 )==0 ) testctrl = SQLITE_TESTCTRL_RESERVE; - else if( strncmp( azArg[1], "optimizations", 3 )==0 ) testctrl = SQLITE_TESTCTRL_OPTIMIZATIONS; - else if( strncmp( azArg[1], "iskeyword", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ISKEYWORD; - else if( strncmp( azArg[1], "pghdrsz", 3 )==0 ) testctrl = SQLITE_TESTCTRL_PGHDRSZ; - else if( strncmp( azArg[1], "scratchmalloc", 3 )==0 ) testctrl = SQLITE_TESTCTRL_SCRATCHMALLOC; - else testctrl = atoi(azArg[1]); - + /* convert testctrl text option to value. allow any unique prefix + ** of the option name, or a numerical value. */ + n = strlen(azArg[1]); + for(i=0; iSQLITE_TESTCTRL_LAST) ){ fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); }else{ @@ -2209,7 +2225,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = sqlite3_test_control(testctrl, p->db, opt); printf("%d (0x%08x)\n", rc, rc); } else { - fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); + fprintf(stderr,"Error: testctrl %s takes a single int option\n", + azArg[1]); } break; @@ -2233,7 +2250,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = sqlite3_test_control(testctrl, opt); printf("%d (0x%08x)\n", rc, rc); } else { - fprintf(stderr,"Error: testctrl %s takes a single unsigned int option\n", azArg[1]); + fprintf(stderr,"Error: testctrl %s takes a single unsigned" + " int option\n", azArg[1]); } break; @@ -2245,7 +2263,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = sqlite3_test_control(testctrl, opt); printf("%d (0x%08x)\n", rc, rc); } else { - fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); + fprintf(stderr,"Error: testctrl %s takes a single int option\n", + azArg[1]); } break; @@ -2257,7 +2276,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = sqlite3_test_control(testctrl, opt); printf("%d (0x%08x)\n", rc, rc); } else { - fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]); + fprintf(stderr,"Error: testctrl %s takes a single char * option\n", + azArg[1]); } break; #endif @@ -2267,7 +2287,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: case SQLITE_TESTCTRL_SCRATCHMALLOC: default: - fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", azArg[1]); + fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", + azArg[1]); break; } } @@ -2278,7 +2299,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){ sqlite3_busy_timeout(p->db, atoi(azArg[1])); }else - if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){ + if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 + && nArg==2 + ){ enableTimer = booleanValue(azArg[1]); }else @@ -2465,7 +2488,9 @@ static int process_input(struct callback_data *p, FILE *in){ } } if( zSql ){ - if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); + if( !_all_whitespace(zSql) ){ + fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); + } free(zSql); } free(zLine);