From 0c2694b744f33a5725fb0659b4f4c72d9e54b9da Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Sep 2009 16:23:44 +0000 Subject: [PATCH 1/4] Add the "unix-wfl" VFS that does whole-file locking in order to help NFS do better cache coherency. FossilOrigin-Name: 2aeab80e5b84f5e94c5c99b4adeca805601c844b --- manifest | 18 +++--- manifest.uuid | 2 +- src/os_unix.c | 160 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 128 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index 4094f74f1c..8abf794db8 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Do\snot\sreuse\sfunction\sparameters\sin\ssubsequent\sexpressions\ssince\sthe\s\nfunction\scall\smight\shave\striggered\sa\stext\sencoding\schange.\nFix\sfor\sticket\s[2ea2425d34be]. -D 2009-09-03T01:18:01 +C Add\sthe\s"unix-wfl"\sVFS\sthat\sdoes\swhole-file\slocking\sin\sorder\sto\shelp\sNFS\ndo\sbetter\scache\scoherency. +D 2009-09-03T16:23:45 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -148,7 +148,7 @@ F src/os.c 9fea283e336ee31caa4654d6cb05a129a1c42d2f F src/os.h 00a1334a4eecee7f7bef79ac606b88d325119f21 F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5 -F src/os_unix.c f14ff07aec3c3c0796e1a743d1bdafddc15d1af1 +F src/os_unix.c 52b10971479bb77c0c1ed334f0a73cd87b972ee0 F src/os_win.c 58bb163f327e79726dd119344d908e4d98483c3f F src/pager.c ebd0a8f2421e8f0ad5b78201440004bf3e1c96d8 F src/pager.h 11852d044c86cf5a9d6e34171fb0c4fcf1f6265f @@ -753,14 +753,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 69055e9b4cb6346e9e10fd9dd65e6ea06b959e76 -R 7bf564b16edb1681dea7652f8bb4c7d7 +P f22e388727f0ba0f187cdee51ff8ba17a5d50b8a +R 318d6752e52f7f4a033e61119f592643 U drh -Z 7cf4ebdc1da81063254cac877fefb993 +Z 47965b78e770a8b1304310d0ee191e44 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFKnxlMoxKgR168RlERApcIAJ97EhKOwWFb+tWJWmzMa9COqA10WACfVx0d -/MeR2s3kHlBnnVZggaFCIXs= -=s4CU +iD8DBQFKn+2UoxKgR168RlERAv/sAJ4sxtNY+4TxErcLxEqGtbpkH3VwnQCgi8kz +7ozoBqiBdahO12HaBHgOl6c= +=OZsT -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 5d3776b83b..d0e52015c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f22e388727f0ba0f187cdee51ff8ba17a5d50b8a \ No newline at end of file +2aeab80e5b84f5e94c5c99b4adeca805601c844b \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 15bd8cc638..83e9ce2315 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -195,6 +195,7 @@ struct unixFile { int lastErrno; /* The unix errno from the last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + int fileFlags; /* Miscellanous flags */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -225,6 +226,11 @@ 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 */ @@ -1149,6 +1155,62 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ return rc; } +/* +** Perform a file locking operation on a range of bytes in a file. +** The "op" parameter should be one of F_RDLCK, F_WRLCK, or F_UNLCK. +** Return 0 on success or -1 for failure. On failure, write the error +** code into *pErrcode. +** +** If the SQLITE_WHOLE_FILE_LOCKING bit is clear, then only lock +** the range of bytes on the locking page between SHARED_FIRST and +** SHARED_SIZE. If SQLITE_WHOLE_FILE_LOCKING is set, then lock all +** bytes from 0 up to but not including PENDING_BYTE, and all bytes +** that follow SHARED_FIRST. +** +** In other words, of SQLITE_WHOLE_FILE_LOCKING if false (the historical +** default case) then only lock a small range of bytes from SHARED_FIRST +** through SHARED_FIRST+SHARED_SIZE-1. But if SQLITE_WHOLE_FILE_LOCKING is +** true then lock every byte in the file except for PENDING_BYTE and +** RESERVED_BYTE. +** +** SQLITE_WHOLE_FILE_LOCKING=true overlaps SQLITE_WHOLE_FILE_LOCKING=false +** and so the locking schemes are compatible. One type of lock will +** effectively exclude the other type. The reason for using the +** SQLITE_WHOLE_FILE_LOCKING=true is that by indicating the full range +** of bytes to be read or written, we give hints to NFS to help it +** maintain cache coherency. On the other hand, whole file locking +** is slower, so we don't want to use it except for NFS. +*/ +static int rangeLock(unixFile *pFile, int op, int *pErrcode){ + struct flock lock; + int rc; + lock.l_type = op; + lock.l_start = SHARED_FIRST; + lock.l_whence = SEEK_SET; + if( (pFile->fileFlags & SQLITE_WHOLE_FILE_LOCKING)==0 ){ + lock.l_len = SHARED_SIZE; + rc = fcntl(pFile->h, F_SETLK, &lock); + *pErrcode = errno; + }else{ + lock.l_len = 0; + rc = fcntl(pFile->h, F_SETLK, &lock); + *pErrcode = errno; + if( NEVER(op==F_UNLCK) || rc!=(-1) ){ + lock.l_start = 0; + lock.l_len = PENDING_BYTE; + rc = fcntl(pFile->h, F_SETLK, &lock); + if( ALWAYS(op!=F_UNLCK) && rc==(-1) ){ + *pErrcode = errno; + lock.l_type = F_UNLCK; + lock.l_start = SHARED_FIRST; + lock.l_len = 0; + fcntl(pFile->h, F_SETLK, &lock); + } + } + } + return rc; +} + /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: @@ -1217,6 +1279,7 @@ static int unixLock(sqlite3_file *id, int locktype){ struct unixLockInfo *pLock = pFile->pLock; struct flock lock; int s; + int tErrno; assert( pFile ); OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, @@ -1233,7 +1296,10 @@ static int unixLock(sqlite3_file *id, int locktype){ return SQLITE_OK; } - /* Make sure the locking sequence is correct + /* Make sure the locking sequence is correct. + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pendig lock. + ** (3) A shared lock is always held when a reserve lock is requested. */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); @@ -1277,14 +1343,13 @@ static int unixLock(sqlite3_file *id, int locktype){ goto end_lock; } - lock.l_len = 1L; - - lock.l_whence = SEEK_SET; /* A PENDING lock is needed before acquiring a SHARED lock and before ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will ** be released. */ + lock.l_len = 1L; + lock.l_whence = SEEK_SET; if( locktype==SHARED_LOCK || (locktype==EXCLUSIVE_LOCK && pFile->locktypeh, F_SETLK, &lock); if( s==(-1) ){ - int tErrno = errno; + tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -1306,16 +1371,12 @@ static int unixLock(sqlite3_file *id, int locktype){ ** operating system calls for the specified lock. */ if( locktype==SHARED_LOCK ){ - int tErrno = 0; assert( pLock->cnt==0 ); assert( pLock->locktype==0 ); /* Now get the read-lock */ - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){ - tErrno = errno; - } + s = rangeLock(pFile, F_RDLCK, &tErrno); + /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; @@ -1355,17 +1416,16 @@ static int unixLock(sqlite3_file *id, int locktype){ switch( locktype ){ case RESERVED_LOCK: lock.l_start = RESERVED_BYTE; + s = fcntl(pFile->h, F_SETLK, &lock); + tErrno = errno; break; case EXCLUSIVE_LOCK: - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; + s = rangeLock(pFile, F_WRLCK, &tErrno); break; default: assert(0); } - s = fcntl(pFile->h, F_SETLK, &lock); if( s==(-1) ){ - int tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -1457,11 +1517,12 @@ static void setPendingFd(unixFile *pFile){ ** the requested locking level, this routine is a no-op. */ static int unixUnlock(sqlite3_file *id, int locktype){ - struct unixLockInfo *pLock; - struct flock lock; - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - int h; + unixFile *pFile = (unixFile*)id; /* The open file */ + struct unixLockInfo *pLock; /* Structure describing current lock state */ + struct flock lock; /* Information passed into fcntl() */ + int rc = SQLITE_OK; /* Return code from this interface */ + int h; /* The underlying file descriptor */ + int tErrno; /* Error code from system call errors */ assert( pFile ); OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype, @@ -1501,12 +1562,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ if( locktype==SHARED_LOCK ){ - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ - int tErrno = errno; + if( rangeLock(pFile, F_RDLCK, &tErrno)==(-1) ){ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -1521,7 +1577,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ if( fcntl(h, F_SETLK, &lock)!=(-1) ){ pLock->locktype = SHARED_LOCK; }else{ - int tErrno = errno; + tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -1547,7 +1603,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ if( fcntl(h, F_SETLK, &lock)!=(-1) ){ pLock->locktype = NO_LOCK; }else{ - int tErrno = errno; + tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -1696,7 +1752,7 @@ static int nolockClose(sqlite3_file *id) { /****************************************************************************** ************************* Begin dot-file Locking ****************************** ** -** The dotfile locking implementation uses the existing of separate lock +** The dotfile locking implementation uses the existance of separate lock ** files in order to control access to the database. This works on just ** about every filesystem imaginable. But there are serious downsides: ** @@ -3199,11 +3255,11 @@ static const sqlite3_io_methods METHOD = { \ unixSectorSize, /* xSectorSize */ \ unixDeviceCharacteristics /* xDeviceCapabilities */ \ }; \ -static const sqlite3_io_methods *FINDER##Impl(const char *z, int h){ \ - UNUSED_PARAMETER(z); UNUSED_PARAMETER(h); \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ + UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ return &METHOD; \ } \ -static const sqlite3_io_methods *(*const FINDER)(const char*,int) \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ = FINDER##Impl; /* @@ -3269,6 +3325,23 @@ IOMETHODS( ) #endif +/* +** The "Whole File Locking" finder returns the same set of methods as +** the posix locking finder. But it also sets the SQLITE_WHOLE_FILE_LOCKING +** flag to force the posix advisory locks to cover the whole file instead +** of just a small span of bytes near the 1GiB boundary. Whole File Locking +** is useful on NFS-mounted files since it helps NFS to maintain cache +** coherency. But it is a detriment to other filesystems since it runs +** slower. +*/ +static const sqlite3_io_methods *posixWflIoFinderImpl(const char*z, unixFile*p){ + UNUSED_PARAMETER(z); + p->fileFlags = SQLITE_WHOLE_FILE_LOCKING; + return &posixIoMethods; +} +static const sqlite3_io_methods + *(*const posixWflIoFinder)(const char*,unixFile *p) = posixWflIoFinderImpl; + /* ** The proxy locking method is a "super-method" in the sense that it ** opens secondary file descriptors for the conch and lock files and @@ -3304,7 +3377,7 @@ IOMETHODS( */ static const sqlite3_io_methods *autolockIoFinderImpl( const char *filePath, /* name of the database file */ - int fd /* file descriptor open on the database file */ + unixFile *pNew /* open file object for the database file */ ){ static const struct Mapping { const char *zFilesystem; /* Filesystem type name */ @@ -3349,14 +3422,15 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { + if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + pNew->fileFlags = SQLITE_WHOLE_FILE_LOCKING; return &posixIoMethods; }else{ return &dotlockIoMethods; } } -static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int) - = autolockIoFinderImpl; +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ @@ -3370,7 +3444,7 @@ static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int) */ static const sqlite3_io_methods *autolockIoFinderImpl( const char *filePath, /* name of the database file */ - int fd /* file descriptor open on the database file */ + unixFile *pNew /* the open file object */ ){ struct flock lockInfo; @@ -3387,21 +3461,21 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { + if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { return &posixIoMethods; }else{ return &semIoMethods; } } -static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int) - = autolockIoFinderImpl; +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ /* ** An abstract type for a pointer to a IO method finder function: */ -typedef const sqlite3_io_methods *(*finder_type)(const char*,int); +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); /**************************************************************************** @@ -3439,6 +3513,7 @@ static int fillInUnixFile( pNew->h = h; pNew->dirfd = dirfd; SET_THREADID(pNew); + pNew->fileFlags = 0; #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); @@ -3451,7 +3526,7 @@ static int fillInUnixFile( if( noLock ){ pLockingStyle = &nolockIoMethods; }else{ - pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, h); + pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); #if SQLITE_ENABLE_LOCKING_STYLE /* Cache zFilename in the locking context (AFP and dotlock override) for ** proxyLock activation is possible (remote proxy is based on db name) @@ -5266,6 +5341,7 @@ int sqlite3_os_init(void){ #endif UNIXVFS("unix-none", nolockIoFinder ), UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-wfl", posixWflIoFinder ), #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif From dcabfcee270e66766305ff728b7ddfaa683efe35 Mon Sep 17 00:00:00 2001 From: shane Date: Mon, 7 Sep 2009 02:46:31 +0000 Subject: [PATCH 2/4] Changes to internal AtoF to improve "accuracy" when measured against built-in GCC atof(). FossilOrigin-Name: 438e1577d0f9ceb2851ee0df0df18f0229eca491 --- manifest | 24 +- manifest.uuid | 2 +- src/util.c | 2161 +++++++++++++++++++++++++------------------------ 3 files changed, 1090 insertions(+), 1097 deletions(-) diff --git a/manifest b/manifest index 8abf794db8..d97af3eed7 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Add\sthe\s"unix-wfl"\sVFS\sthat\sdoes\swhole-file\slocking\sin\sorder\sto\shelp\sNFS\ndo\sbetter\scache\scoherency. -D 2009-09-03T16:23:45 +C Changes\sto\sinternal\sAtoF\sto\simprove\s"accuracy"\swhen\smeasured\sagainst\sbuilt-in\sGCC\satof(). +D 2009-09-07T02:46:32 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -206,7 +203,7 @@ F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b F src/trigger.c 8158237fc5fa4b51a126a294791729c64d27a0a9 F src/update.c 12ffd68c2f241c730d5e051eb29b23e90682ff8a F src/utf.c 3ca2c9461b8e942c68da28bfccd448663f536a6f -F src/util.c efb5f8e533d4beef545cf765cab5f7920b4c75f9 +F src/util.c 7404ac078125aafc0e274b2d1a918c3f15b50294 F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0 F src/vdbe.c addf5f6fefe9b9c6ca8819efbf52cfce8bd68089 F src/vdbe.h 080fe6bc1264438becb8bf9b9f3c84074c336b78 @@ -753,14 +750,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f22e388727f0ba0f187cdee51ff8ba17a5d50b8a -R 318d6752e52f7f4a033e61119f592643 -U drh -Z 47965b78e770a8b1304310d0ee191e44 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFKn+2UoxKgR168RlERAv/sAJ4sxtNY+4TxErcLxEqGtbpkH3VwnQCgi8kz -7ozoBqiBdahO12HaBHgOl6c= -=OZsT ------END PGP SIGNATURE----- +P 2aeab80e5b84f5e94c5c99b4adeca805601c844b +R 0b92cbb9074dfe690c0e4c14e6998bde +U shane +Z 82d0c356acbda85944f3ae28efe12d94 diff --git a/manifest.uuid b/manifest.uuid index d0e52015c5..fb0b520154 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2aeab80e5b84f5e94c5c99b4adeca805601c844b \ No newline at end of file +438e1577d0f9ceb2851ee0df0df18f0229eca491 \ No newline at end of file diff --git a/src/util.c b/src/util.c index ef291b94b3..085d7140e4 100644 --- a/src/util.c +++ b/src/util.c @@ -1,1079 +1,1082 @@ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Utility functions used throughout sqlite. -** -** This file contains functions for allocating memory, comparing -** strings, and stuff like that. -** -*/ -#include "sqliteInt.h" -#include -#ifdef SQLITE_HAVE_ISNAN -# include -#endif - -/* -** Routine needed to support the testcase() macro. -*/ -#ifdef SQLITE_COVERAGE_TEST -void sqlite3Coverage(int x){ - static int dummy = 0; - dummy += x; -} -#endif - -/* -** Return true if the floating point value is Not a Number (NaN). -** -** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. -** Otherwise, we have our own implementation that works on most systems. -*/ -int sqlite3IsNaN(double x){ - int rc; /* The value return */ -#if !defined(SQLITE_HAVE_ISNAN) - /* - ** Systems that support the isnan() library function should probably - ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have - ** found that many systems do not have a working isnan() function so - ** this implementation is provided as an alternative. - ** - ** This NaN test sometimes fails if compiled on GCC with -ffast-math. - ** On the other hand, the use of -ffast-math comes with the following - ** warning: - ** - ** This option [-ffast-math] should never be turned on by any - ** -O option since it can result in incorrect output for programs - ** which depend on an exact implementation of IEEE or ISO - ** rules/specifications for math functions. - ** - ** Under MSVC, this NaN test may fail if compiled with a floating- - ** point precision mode other than /fp:precise. From the MSDN - ** documentation: - ** - ** The compiler [with /fp:precise] will properly handle comparisons - ** involving NaN. For example, x != x evaluates to true if x is NaN - ** ... - */ -#ifdef __FAST_MATH__ -# error SQLite will not work correctly with the -ffast-math option of GCC. -#endif - volatile double y = x; - volatile double z = y; - rc = (y!=z); -#else /* if defined(SQLITE_HAVE_ISNAN) */ - rc = isnan(x); -#endif /* SQLITE_HAVE_ISNAN */ - testcase( rc ); - return rc; -} - -/* -** Compute a string length that is limited to what can be stored in -** lower 30 bits of a 32-bit signed integer. -** -** The value returned will never be negative. Nor will it ever be greater -** than the actual length of the string. For very long strings (greater -** than 1GiB) the value returned might be less than the true string length. -*/ -int sqlite3Strlen30(const char *z){ - const char *z2 = z; - if( z==0 ) return 0; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); -} - -/* -** Set the most recent error code and error string for the sqlite -** handle "db". The error code is set to "err_code". -** -** If it is not NULL, string zFormat specifies the format of the -** error string in the style of the printf functions: The following -** format characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** zFormat and any string tokens that follow it are assumed to be -** encoded in UTF-8. -** -** To clear the most recent error for sqlite handle "db", sqlite3Error -** should be called with err_code set to SQLITE_OK and zFormat set -** to NULL. -*/ -void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){ - if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){ - db->errCode = err_code; - if( zFormat ){ - char *z; - va_list ap; - va_start(ap, zFormat); - z = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); - }else{ - sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC); - } - } -} - -/* -** Add an error message to pParse->zErrMsg and increment pParse->nErr. -** The following formatting characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** This function should be used to report any error that occurs whilst -** compiling an SQL statement (i.e. within sqlite3_prepare()). The -** last thing the sqlite3_prepare() function does is copy the error -** stored by this function into the database handle using sqlite3Error(). -** Function sqlite3Error() should be used during statement execution -** (sqlite3_step() etc.). -*/ -void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ - va_list ap; - sqlite3 *db = pParse->db; - pParse->nErr++; - sqlite3DbFree(db, pParse->zErrMsg); - va_start(ap, zFormat); - pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - pParse->rc = SQLITE_ERROR; -} - -/* -** Clear the error message in pParse, if any -*/ -void sqlite3ErrorClear(Parse *pParse){ - sqlite3DbFree(pParse->db, pParse->zErrMsg); - pParse->zErrMsg = 0; - pParse->nErr = 0; -} - -/* -** Convert an SQL-style quoted string into a normal string by removing -** the quote characters. The conversion is done in-place. If the -** input does not begin with a quote character, then this routine -** is a no-op. -** -** The input string must be zero-terminated. A new zero-terminator -** is added to the dequoted string. -** -** The return value is -1 if no dequoting occurs or the length of the -** dequoted string, exclusive of the zero terminator, if dequoting does -** occur. -** -** 2002-Feb-14: This routine is extended to remove MS-Access style -** brackets from around identifers. For example: "[a-b-c]" becomes -** "a-b-c". -*/ -int sqlite3Dequote(char *z){ - char quote; - int i, j; - if( z==0 ) return -1; - quote = z[0]; - switch( quote ){ - case '\'': break; - case '"': break; - case '`': break; /* For MySQL compatibility */ - case '[': quote = ']'; break; /* For MS SqlServer compatibility */ - default: return -1; - } - for(i=1, j=0; ALWAYS(z[i]); i++){ - if( z[i]==quote ){ - if( z[i+1]==quote ){ - z[j++] = quote; - i++; - }else{ - break; - } - }else{ - z[j++] = z[i]; - } - } - z[j] = 0; - return j; -} - -/* Convenient short-hand */ -#define UpperToLower sqlite3UpperToLower - -/* -** Some systems have stricmp(). Others have strcasecmp(). Because -** there is no consistency, we will define our own. -*/ -int sqlite3StrICmp(const char *zLeft, const char *zRight){ - register unsigned char *a, *b; - a = (unsigned char *)zLeft; - b = (unsigned char *)zRight; - while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } - return UpperToLower[*a] - UpperToLower[*b]; -} -int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ - register unsigned char *a, *b; - a = (unsigned char *)zLeft; - b = (unsigned char *)zRight; - while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } - return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; -} - -/* -** Return TRUE if z is a pure numeric string. Return FALSE and leave -** *realnum unchanged if the string contains any character which is not -** part of a number. -** -** If the string is pure numeric, set *realnum to TRUE if the string -** contains the '.' character or an "E+000" style exponentiation suffix. -** Otherwise set *realnum to FALSE. Note that just becaue *realnum is -** false does not mean that the number can be successfully converted into -** an integer - it might be too big. -** -** An empty string is considered non-numeric. -*/ -int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ - int incr = (enc==SQLITE_UTF8?1:2); - if( enc==SQLITE_UTF16BE ) z++; - if( *z=='-' || *z=='+' ) z += incr; - if( !sqlite3Isdigit(*z) ){ - return 0; - } - z += incr; - *realnum = 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - if( *z=='.' ){ - z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z += incr; - if( *z=='+' || *z=='-' ) z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } - return *z==0; -} - -/* -** The string z[] is an ASCII representation of a real number. -** Convert this string to a double. -** -** This routine assumes that z[] really is a valid number. If it -** is not, the result is undefined. -** -** This routine is used instead of the library atof() function because -** the library atof() might want to use "," as the decimal point instead -** of "." depending on how locale is set. But that would cause problems -** for SQL. So this routine always uses "." regardless of locale. -*/ -int sqlite3AtoF(const char *z, double *pResult){ -#ifndef SQLITE_OMIT_FLOATING_POINT - const char *zBegin = z; - /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ - double result; - int nDigits = 0; - - /* skip leading spaces */ - while( sqlite3Isspace(*z) ) z++; - /* get sign of significand */ - if( *z=='-' ){ - sign = -1; - z++; - }else if( *z=='+' ){ - z++; - } - /* skip leading zeroes */ - while( z[0]=='0' ) z++, nDigits++; - - /* copy max significant digits to significand */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ - s = s*10 + (*z - '0'); - z++, nDigits++; - } - /* skip non-significant significand digits - ** (increase exponent by d to shift decimal left) */ - while( sqlite3Isdigit(*z) ) z++, nDigits++, d++; - - /* if decimal point is present */ - if( *z=='.' ){ - z++; - /* copy digits from after decimal to significand - ** (decrease exponent by d to shift decimal right) */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ - s = s*10 + (*z - '0'); - z++, nDigits++, d--; - } - /* skip non-significant digits */ - while( sqlite3Isdigit(*z) ) z++, nDigits++; - } - - /* if exponent is present */ - if( *z=='e' || *z=='E' ){ - z++; - /* get sign of exponent */ - if( *z=='-' ){ - esign = -1; - z++; - }else if( *z=='+' ){ - z++; - } - /* copy digits to exponent */ - while( sqlite3Isdigit(*z) ){ - e = e*10 + (*z - '0'); - z++; - } - } - - /* adjust exponent by d, and update sign */ - e = (e*esign) + d; - if( e<0 ) { - esign = -1; - e *= -1; - } else { - esign = 1; - } - - /* if 0 significand */ - if( !s ) { - /* In the IEEE 754 standard, zero is signed. - ** Add the sign if we've seen at least one digit */ - result = (sign<0 && nDigits) ? -(double)0 : (double)0; - } else { - /* attempt to reduce exponent */ - if( esign>0 ){ - while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; - } - - /* adjust the sign of significand */ - s = sign<0 ? -s : s; - - /* if exponent, scale significand as appropriate - ** and store in result. */ - if( e ){ - double scale = 1.0; - while( e>=16 ){ scale *= 1.0e+16; e -= 16; } - while( e>=4 ){ scale *= 1.0e+4; e -= 4; } - while( e>=1 ){ scale *= 1.0e+1; e -= 1; } - if( esign<0 ){ - result = s / scale; - }else{ - result = s * scale; - } - } else { - result = (double)s; - } - } - - /* store the result */ - *pResult = result; - - /* return number of characters used */ - return (int)(z - zBegin); -#else - return sqlite3Atoi64(z, pResult); -#endif /* SQLITE_OMIT_FLOATING_POINT */ -} - -/* -** Compare the 19-character string zNum against the text representation -** value 2^63: 9223372036854775808. Return negative, zero, or positive -** if zNum is less than, equal to, or greater than the string. -** -** Unlike memcmp() this routine is guaranteed to return the difference -** in the values of the last digit if the only difference is in the -** last digit. So, for example, -** -** compare2pow63("9223372036854775800") -** -** will return -8. -*/ -static int compare2pow63(const char *zNum){ - int c; - c = memcmp(zNum,"922337203685477580",18)*10; - if( c==0 ){ - c = zNum[18] - '8'; - } - return c; -} - - -/* -** Return TRUE if zNum is a 64-bit signed integer and write -** the value of the integer into *pNum. If zNum is not an integer -** or is an integer that is too large to be expressed with 64 bits, -** then return false. -** -** When this routine was originally written it dealt with only -** 32-bit numbers. At that time, it was much faster than the -** atoi() library routine in RedHat 7.2. -*/ -int sqlite3Atoi64(const char *zNum, i64 *pNum){ - i64 v = 0; - int neg; - int i, c; - const char *zStart; - while( sqlite3Isspace(*zNum) ) zNum++; - if( *zNum=='-' ){ - neg = 1; - zNum++; - }else if( *zNum=='+' ){ - neg = 0; - zNum++; - }else{ - neg = 0; - } - zStart = zNum; - while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */ - for(i=0; (c=zNum[i])>='0' && c<='9'; i++){ - v = v*10 + c - '0'; - } - *pNum = neg ? -v : v; - if( c!=0 || (i==0 && zStart==zNum) || i>19 ){ - /* zNum is empty or contains non-numeric text or is longer - ** than 19 digits (thus guaranting that it is too large) */ - return 0; - }else if( i<19 ){ - /* Less than 19 digits, so we know that it fits in 64 bits */ - return 1; - }else{ - /* 19-digit numbers must be no larger than 9223372036854775807 if positive - ** or 9223372036854775808 if negative. Note that 9223372036854665808 - ** is 2^63. */ - return compare2pow63(zNum)='0' && zNum[0]<='9' ); /* zNum is an unsigned number */ - - if( negFlag ) neg = 1-neg; - while( *zNum=='0' ){ - zNum++; /* Skip leading zeros. Ticket #2454 */ - } - for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); } - if( i<19 ){ - /* Guaranteed to fit if less than 19 digits */ - return 1; - }else if( i>19 ){ - /* Guaranteed to be too big if greater than 19 digits */ - return 0; - }else{ - /* Compare against 2^63. */ - return compare2pow63(zNum)=0 && c<=9; i++){ - v = v*10 + c; - } - - /* The longest decimal representation of a 32 bit integer is 10 digits: - ** - ** 1234567890 - ** 2^31 -> 2147483648 - */ - if( i>10 ){ - return 0; - } - if( v-neg>2147483647 ){ - return 0; - } - if( neg ){ - v = -v; - } - *pValue = (int)v; - return 1; -} - -/* -** The variable-length integer encoding is as follows: -** -** KEY: -** A = 0xxxxxxx 7 bits of data and one flag bit -** B = 1xxxxxxx 7 bits of data and one flag bit -** C = xxxxxxxx 8 bits of data -** -** 7 bits - A -** 14 bits - BA -** 21 bits - BBA -** 28 bits - BBBA -** 35 bits - BBBBA -** 42 bits - BBBBBA -** 49 bits - BBBBBBA -** 56 bits - BBBBBBBA -** 64 bits - BBBBBBBBC -*/ - -/* -** Write a 64-bit variable-length integer to memory starting at p[0]. -** The length of data write will be between 1 and 9 bytes. The number -** of bytes written is returned. -** -** A variable-length integer consists of the lower 7 bits of each byte -** for all bytes that have the 8th bit set and one byte with the 8th -** bit clear. Except, if we get to the 9th byte, it stores the full -** 8 bits and is the last byte. -*/ -int sqlite3PutVarint(unsigned char *p, u64 v){ - int i, j, n; - u8 buf[10]; - if( v & (((u64)0xff000000)<<32) ){ - p[8] = (u8)v; - v >>= 8; - for(i=7; i>=0; i--){ - p[i] = (u8)((v & 0x7f) | 0x80); - v >>= 7; - } - return 9; - } - n = 0; - do{ - buf[n++] = (u8)((v & 0x7f) | 0x80); - v >>= 7; - }while( v!=0 ); - buf[0] &= 0x7f; - assert( n<=9 ); - for(i=0, j=n-1; j>=0; j--, i++){ - p[i] = buf[j]; - } - return n; -} - -/* -** This routine is a faster version of sqlite3PutVarint() that only -** works for 32-bit positive integers and which is optimized for -** the common case of small integers. A MACRO version, putVarint32, -** is provided which inlines the single-byte case. All code should use -** the MACRO version as this function assumes the single-byte case has -** already been handled. -*/ -int sqlite3PutVarint32(unsigned char *p, u32 v){ -#ifndef putVarint32 - if( (v & ~0x7f)==0 ){ - p[0] = v; - return 1; - } -#endif - if( (v & ~0x3fff)==0 ){ - p[0] = (u8)((v>>7) | 0x80); - p[1] = (u8)(v & 0x7f); - return 2; - } - return sqlite3PutVarint(p, v); -} - -/* -** Read a 64-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read. The value is stored in *v. -*/ -u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ - u32 a,b,s; - - a = *p; - /* a: p0 (unmasked) */ - if (!(a&0x80)) - { - *v = a; - return 1; - } - - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - a &= 0x7f; - a = a<<7; - a |= b; - *v = a; - return 2; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - a |= b; - *v = a; - return 3; - } - - /* CSE1 from below */ - a &= (0x7f<<14)|(0x7f); - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - b &= (0x7f<<14)|(0x7f); - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - *v = a; - return 4; - } - - /* a: p0<<14 | p2 (masked) */ - /* b: p1<<14 | p3 (unmasked) */ - /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - b &= (0x7f<<14)|(0x7f); - s = a; - /* s: p0<<14 | p2 (masked) */ - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* we can skip these cause they were (effectively) done above in calc'ing s */ - /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - /* b &= (0x7f<<14)|(0x7f); */ - b = b<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 5; - } - - /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - s = s<<7; - s |= b; - /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - - p++; - b = b<<14; - b |= *p; - /* b: p1<<28 | p3<<14 | p5 (unmasked) */ - if (!(b&0x80)) - { - /* we can skip this cause it was (effectively) done above in calc'ing s */ - /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - a &= (0x7f<<14)|(0x7f); - a = a<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 6; - } - - p++; - a = a<<14; - a |= *p; - /* a: p2<<28 | p4<<14 | p6 (unmasked) */ - if (!(a&0x80)) - { - a &= (0x1f<<28)|(0x7f<<14)|(0x7f); - b &= (0x7f<<14)|(0x7f); - b = b<<7; - a |= b; - s = s>>11; - *v = ((u64)s)<<32 | a; - return 7; - } - - /* CSE2 from below */ - a &= (0x7f<<14)|(0x7f); - p++; - b = b<<14; - b |= *p; - /* b: p3<<28 | p5<<14 | p7 (unmasked) */ - if (!(b&0x80)) - { - b &= (0x1f<<28)|(0x7f<<14)|(0x7f); - /* moved CSE2 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - s = s>>4; - *v = ((u64)s)<<32 | a; - return 8; - } - - p++; - a = a<<15; - a |= *p; - /* a: p4<<29 | p6<<15 | p8 (unmasked) */ - - /* moved CSE2 up */ - /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ - b &= (0x7f<<14)|(0x7f); - b = b<<8; - a |= b; - - s = s<<4; - b = p[-4]; - b &= 0x7f; - b = b>>3; - s |= b; - - *v = ((u64)s)<<32 | a; - - return 9; -} - -/* -** Read a 32-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read. The value is stored in *v. -** -** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned -** integer, then set *v to 0xffffffff. -** -** A MACRO version, getVarint32, is provided which inlines the -** single-byte case. All code should use the MACRO version as -** this function assumes the single-byte case has already been handled. -*/ -u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u32 a,b; - - /* The 1-byte case. Overwhelmingly the most common. Handled inline - ** by the getVarin32() macro */ - a = *p; - /* a: p0 (unmasked) */ -#ifndef getVarint32 - if (!(a&0x80)) - { - /* Values between 0 and 127 */ - *v = a; - return 1; - } -#endif - - /* The 2-byte case */ - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 128 and 16383 */ - a &= 0x7f; - a = a<<7; - *v = a | b; - return 2; - } - - /* The 3-byte case */ - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 16384 and 2097151 */ - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - *v = a | b; - return 3; - } - - /* A 32-bit varint is used to store size information in btrees. - ** Objects are rarely larger than 2MiB limit of a 3-byte varint. - ** A 3-byte varint is sufficient, for example, to record the size - ** of a 1048569-byte BLOB or string. - ** - ** We only unroll the first 1-, 2-, and 3- byte cases. The very - ** rare larger cases can be handled by the slower 64-bit varint - ** routine. - */ -#if 1 - { - u64 v64; - u8 n; - - p -= 2; - n = sqlite3GetVarint(p, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ - *v = (u32)v64; - } - return n; - } - -#else - /* For following code (kept for historical record only) shows an - ** unrolling for the 3- and 4-byte varint cases. This code is - ** slightly faster, but it is also larger and much harder to test. - */ - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 2097152 and 268435455 */ - b &= (0x7f<<14)|(0x7f); - a &= (0x7f<<14)|(0x7f); - a = a<<7; - *v = a | b; - return 4; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* Walues between 268435456 and 34359738367 */ - a &= (0x1f<<28)|(0x7f<<14)|(0x7f); - b &= (0x1f<<28)|(0x7f<<14)|(0x7f); - b = b<<7; - *v = a | b; - return 5; - } - - /* We can only reach this point when reading a corrupt database - ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose sqlite3GetVarint() routine to extract the - ** value. */ - { - u64 v64; - u8 n; - - p -= 4; - n = sqlite3GetVarint(p, &v64); - assert( n>5 && n<=9 ); - *v = (u32)v64; - return n; - } -#endif -} - -/* -** Return the number of bytes that will be needed to store the given -** 64-bit integer. -*/ -int sqlite3VarintLen(u64 v){ - int i = 0; - do{ - i++; - v >>= 7; - }while( v!=0 && ALWAYS(i<9) ); - return i; -} - - -/* -** Read or write a four-byte big-endian integer value. -*/ -u32 sqlite3Get4byte(const u8 *p){ - return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; -} -void sqlite3Put4byte(unsigned char *p, u32 v){ - p[0] = (u8)(v>>24); - p[1] = (u8)(v>>16); - p[2] = (u8)(v>>8); - p[3] = (u8)v; -} - - - -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) -/* -** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F -*/ -static u8 hexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); -#ifdef SQLITE_ASCII - h += 9*(1&(h>>6)); -#endif -#ifdef SQLITE_EBCDIC - h += 9*(1&~(h>>4)); -#endif - return (u8)(h & 0xf); -} -#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ - -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) -/* -** Convert a BLOB literal of the form "x'hhhhhh'" into its binary -** value. Return a pointer to its binary value. Space to hold the -** binary value has been obtained from malloc and must be freed by -** the calling routine. -*/ -void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ - char *zBlob; - int i; - - zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1); - n--; - if( zBlob ){ - for(i=0; imagic is not a valid open value, take care not -** to modify the db structure at all. It could be that db is a stale -** pointer. In other words, it could be that there has been a prior -** call to sqlite3_close(db) and db has been deallocated. And we do -** not want to write into deallocated memory. -*/ -#ifdef SQLITE_DEBUG -int sqlite3SafetyOn(sqlite3 *db){ - if( db->magic==SQLITE_MAGIC_OPEN ){ - db->magic = SQLITE_MAGIC_BUSY; - assert( sqlite3_mutex_held(db->mutex) ); - return 0; - }else if( db->magic==SQLITE_MAGIC_BUSY ){ - db->magic = SQLITE_MAGIC_ERROR; - db->u1.isInterrupted = 1; - } - return 1; -} -#endif - -/* -** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN. -** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY -** when this routine is called. -*/ -#ifdef SQLITE_DEBUG -int sqlite3SafetyOff(sqlite3 *db){ - if( db->magic==SQLITE_MAGIC_BUSY ){ - db->magic = SQLITE_MAGIC_OPEN; - assert( sqlite3_mutex_held(db->mutex) ); - return 0; - }else{ - db->magic = SQLITE_MAGIC_ERROR; - db->u1.isInterrupted = 1; - return 1; - } -} -#endif - -/* -** Check to make sure we have a valid db pointer. This test is not -** foolproof but it does provide some measure of protection against -** misuse of the interface such as passing in db pointers that are -** NULL or which have been previously closed. If this routine returns -** 1 it means that the db pointer is valid and 0 if it should not be -** dereferenced for any reason. The calling function should invoke -** SQLITE_MISUSE immediately. -** -** sqlite3SafetyCheckOk() requires that the db pointer be valid for -** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to -** open properly and is not fit for general use but which can be -** used as an argument to sqlite3_errmsg() or sqlite3_close(). -*/ -int sqlite3SafetyCheckOk(sqlite3 *db){ - u32 magic; - if( db==0 ) return 0; - magic = db->magic; - if( magic!=SQLITE_MAGIC_OPEN -#ifdef SQLITE_DEBUG - && magic!=SQLITE_MAGIC_BUSY -#endif - ){ - return 0; - }else{ - return 1; - } -} -int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ - u32 magic; - magic = db->magic; - if( magic!=SQLITE_MAGIC_SICK && - magic!=SQLITE_MAGIC_OPEN && - magic!=SQLITE_MAGIC_BUSY ) return 0; - return 1; -} +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Utility functions used throughout sqlite. +** +** This file contains functions for allocating memory, comparing +** strings, and stuff like that. +** +*/ +#include "sqliteInt.h" +#include +#ifdef SQLITE_HAVE_ISNAN +# include +#endif + +/* +** Routine needed to support the testcase() macro. +*/ +#ifdef SQLITE_COVERAGE_TEST +void sqlite3Coverage(int x){ + static int dummy = 0; + dummy += x; +} +#endif + +/* +** Return true if the floating point value is Not a Number (NaN). +** +** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. +** Otherwise, we have our own implementation that works on most systems. +*/ +int sqlite3IsNaN(double x){ + int rc; /* The value return */ +#if !defined(SQLITE_HAVE_ISNAN) + /* + ** Systems that support the isnan() library function should probably + ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have + ** found that many systems do not have a working isnan() function so + ** this implementation is provided as an alternative. + ** + ** This NaN test sometimes fails if compiled on GCC with -ffast-math. + ** On the other hand, the use of -ffast-math comes with the following + ** warning: + ** + ** This option [-ffast-math] should never be turned on by any + ** -O option since it can result in incorrect output for programs + ** which depend on an exact implementation of IEEE or ISO + ** rules/specifications for math functions. + ** + ** Under MSVC, this NaN test may fail if compiled with a floating- + ** point precision mode other than /fp:precise. From the MSDN + ** documentation: + ** + ** The compiler [with /fp:precise] will properly handle comparisons + ** involving NaN. For example, x != x evaluates to true if x is NaN + ** ... + */ +#ifdef __FAST_MATH__ +# error SQLite will not work correctly with the -ffast-math option of GCC. +#endif + volatile double y = x; + volatile double z = y; + rc = (y!=z); +#else /* if defined(SQLITE_HAVE_ISNAN) */ + rc = isnan(x); +#endif /* SQLITE_HAVE_ISNAN */ + testcase( rc ); + return rc; +} + +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +** +** The value returned will never be negative. Nor will it ever be greater +** than the actual length of the string. For very long strings (greater +** than 1GiB) the value returned might be less than the true string length. +*/ +int sqlite3Strlen30(const char *z){ + const char *z2 = z; + if( z==0 ) return 0; + while( *z2 ){ z2++; } + return 0x3fffffff & (int)(z2 - z); +} + +/* +** Set the most recent error code and error string for the sqlite +** handle "db". The error code is set to "err_code". +** +** If it is not NULL, string zFormat specifies the format of the +** error string in the style of the printf functions: The following +** format characters are allowed: +** +** %s Insert a string +** %z A string that should be freed after use +** %d Insert an integer +** %T Insert a token +** %S Insert the first element of a SrcList +** +** zFormat and any string tokens that follow it are assumed to be +** encoded in UTF-8. +** +** To clear the most recent error for sqlite handle "db", sqlite3Error +** should be called with err_code set to SQLITE_OK and zFormat set +** to NULL. +*/ +void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){ + if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){ + db->errCode = err_code; + if( zFormat ){ + char *z; + va_list ap; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); + }else{ + sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC); + } + } +} + +/* +** Add an error message to pParse->zErrMsg and increment pParse->nErr. +** The following formatting characters are allowed: +** +** %s Insert a string +** %z A string that should be freed after use +** %d Insert an integer +** %T Insert a token +** %S Insert the first element of a SrcList +** +** This function should be used to report any error that occurs whilst +** compiling an SQL statement (i.e. within sqlite3_prepare()). The +** last thing the sqlite3_prepare() function does is copy the error +** stored by this function into the database handle using sqlite3Error(). +** Function sqlite3Error() should be used during statement execution +** (sqlite3_step() etc.). +*/ +void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ + va_list ap; + sqlite3 *db = pParse->db; + pParse->nErr++; + sqlite3DbFree(db, pParse->zErrMsg); + va_start(ap, zFormat); + pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + pParse->rc = SQLITE_ERROR; +} + +/* +** Clear the error message in pParse, if any +*/ +void sqlite3ErrorClear(Parse *pParse){ + sqlite3DbFree(pParse->db, pParse->zErrMsg); + pParse->zErrMsg = 0; + pParse->nErr = 0; +} + +/* +** Convert an SQL-style quoted string into a normal string by removing +** the quote characters. The conversion is done in-place. If the +** input does not begin with a quote character, then this routine +** is a no-op. +** +** The input string must be zero-terminated. A new zero-terminator +** is added to the dequoted string. +** +** The return value is -1 if no dequoting occurs or the length of the +** dequoted string, exclusive of the zero terminator, if dequoting does +** occur. +** +** 2002-Feb-14: This routine is extended to remove MS-Access style +** brackets from around identifers. For example: "[a-b-c]" becomes +** "a-b-c". +*/ +int sqlite3Dequote(char *z){ + char quote; + int i, j; + if( z==0 ) return -1; + quote = z[0]; + switch( quote ){ + case '\'': break; + case '"': break; + case '`': break; /* For MySQL compatibility */ + case '[': quote = ']'; break; /* For MS SqlServer compatibility */ + default: return -1; + } + for(i=1, j=0; ALWAYS(z[i]); i++){ + if( z[i]==quote ){ + if( z[i+1]==quote ){ + z[j++] = quote; + i++; + }else{ + break; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; + return j; +} + +/* Convenient short-hand */ +#define UpperToLower sqlite3UpperToLower + +/* +** Some systems have stricmp(). Others have strcasecmp(). Because +** there is no consistency, we will define our own. +*/ +int sqlite3StrICmp(const char *zLeft, const char *zRight){ + register unsigned char *a, *b; + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } + return UpperToLower[*a] - UpperToLower[*b]; +} +int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ + register unsigned char *a, *b; + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } + return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; +} + +/* +** Return TRUE if z is a pure numeric string. Return FALSE and leave +** *realnum unchanged if the string contains any character which is not +** part of a number. +** +** If the string is pure numeric, set *realnum to TRUE if the string +** contains the '.' character or an "E+000" style exponentiation suffix. +** Otherwise set *realnum to FALSE. Note that just becaue *realnum is +** false does not mean that the number can be successfully converted into +** an integer - it might be too big. +** +** An empty string is considered non-numeric. +*/ +int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ + int incr = (enc==SQLITE_UTF8?1:2); + if( enc==SQLITE_UTF16BE ) z++; + if( *z=='-' || *z=='+' ) z += incr; + if( !sqlite3Isdigit(*z) ){ + return 0; + } + z += incr; + *realnum = 0; + while( sqlite3Isdigit(*z) ){ z += incr; } + if( *z=='.' ){ + z += incr; + if( !sqlite3Isdigit(*z) ) return 0; + while( sqlite3Isdigit(*z) ){ z += incr; } + *realnum = 1; + } + if( *z=='e' || *z=='E' ){ + z += incr; + if( *z=='+' || *z=='-' ) z += incr; + if( !sqlite3Isdigit(*z) ) return 0; + while( sqlite3Isdigit(*z) ){ z += incr; } + *realnum = 1; + } + return *z==0; +} + +/* +** The string z[] is an ASCII representation of a real number. +** Convert this string to a double. +** +** This routine assumes that z[] really is a valid number. If it +** is not, the result is undefined. +** +** This routine is used instead of the library atof() function because +** the library atof() might want to use "," as the decimal point instead +** of "." depending on how locale is set. But that would cause problems +** for SQL. So this routine always uses "." regardless of locale. +*/ +int sqlite3AtoF(const char *z, double *pResult){ +#ifndef SQLITE_OMIT_FLOATING_POINT + const char *zBegin = z; + /* sign * significand * (10 ^ (esign * exponent)) */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + double result; + int nDigits = 0; + + /* skip leading spaces */ + while( sqlite3Isspace(*z) ) z++; + /* get sign of significand */ + if( *z=='-' ){ + sign = -1; + z++; + }else if( *z=='+' ){ + z++; + } + /* skip leading zeroes */ + while( z[0]=='0' ) z++, nDigits++; + + /* copy max significant digits to significand */ + while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + s = s*10 + (*z - '0'); + z++, nDigits++; + } + /* skip non-significant significand digits + ** (increase exponent by d to shift decimal left) */ + while( sqlite3Isdigit(*z) ) z++, nDigits++, d++; + + /* if decimal point is present */ + if( *z=='.' ){ + z++; + /* copy digits from after decimal to significand + ** (decrease exponent by d to shift decimal right) */ + while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + s = s*10 + (*z - '0'); + z++, nDigits++, d--; + } + /* skip non-significant digits */ + while( sqlite3Isdigit(*z) ) z++, nDigits++; + } + + /* if exponent is present */ + if( *z=='e' || *z=='E' ){ + z++; + /* get sign of exponent */ + if( *z=='-' ){ + esign = -1; + z++; + }else if( *z=='+' ){ + z++; + } + /* copy digits to exponent */ + while( sqlite3Isdigit(*z) ){ + e = e*10 + (*z - '0'); + z++; + } + } + + /* adjust exponent by d, and update sign */ + e = (e*esign) + d; + if( e<0 ) { + esign = -1; + e *= -1; + } else { + esign = 1; + } + + /* if 0 significand */ + if( !s ) { + /* In the IEEE 754 standard, zero is signed. + ** Add the sign if we've seen at least one digit */ + result = (sign<0 && nDigits) ? -(double)0 : (double)0; + } else { + /* attempt to reduce exponent */ + if( esign>0 ){ + while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; + }else{ + while( !(s%10) && e>0 ) e--,s/=10; + } + + /* adjust the sign of significand */ + s = sign<0 ? -s : s; + + /* if exponent, scale significand as appropriate + ** and store in result. */ + if( e ){ + double scale = 1.0; + /* 1.0e+22 is the largest power of 10 than can be + ** represented exactly. */ + while( e%22 ) { scale *= 1.0e+1; e -= 1; } + while( e>0 ) { scale *= 1.0e+22; e -= 22; } + if( esign<0 ){ + result = s / scale; + }else{ + result = s * scale; + } + } else { + result = (double)s; + } + } + + /* store the result */ + *pResult = result; + + /* return number of characters used */ + return (int)(z - zBegin); +#else + return sqlite3Atoi64(z, pResult); +#endif /* SQLITE_OMIT_FLOATING_POINT */ +} + +/* +** Compare the 19-character string zNum against the text representation +** value 2^63: 9223372036854775808. Return negative, zero, or positive +** if zNum is less than, equal to, or greater than the string. +** +** Unlike memcmp() this routine is guaranteed to return the difference +** in the values of the last digit if the only difference is in the +** last digit. So, for example, +** +** compare2pow63("9223372036854775800") +** +** will return -8. +*/ +static int compare2pow63(const char *zNum){ + int c; + c = memcmp(zNum,"922337203685477580",18)*10; + if( c==0 ){ + c = zNum[18] - '8'; + } + return c; +} + + +/* +** Return TRUE if zNum is a 64-bit signed integer and write +** the value of the integer into *pNum. If zNum is not an integer +** or is an integer that is too large to be expressed with 64 bits, +** then return false. +** +** When this routine was originally written it dealt with only +** 32-bit numbers. At that time, it was much faster than the +** atoi() library routine in RedHat 7.2. +*/ +int sqlite3Atoi64(const char *zNum, i64 *pNum){ + i64 v = 0; + int neg; + int i, c; + const char *zStart; + while( sqlite3Isspace(*zNum) ) zNum++; + if( *zNum=='-' ){ + neg = 1; + zNum++; + }else if( *zNum=='+' ){ + neg = 0; + zNum++; + }else{ + neg = 0; + } + zStart = zNum; + while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */ + for(i=0; (c=zNum[i])>='0' && c<='9'; i++){ + v = v*10 + c - '0'; + } + *pNum = neg ? -v : v; + if( c!=0 || (i==0 && zStart==zNum) || i>19 ){ + /* zNum is empty or contains non-numeric text or is longer + ** than 19 digits (thus guaranting that it is too large) */ + return 0; + }else if( i<19 ){ + /* Less than 19 digits, so we know that it fits in 64 bits */ + return 1; + }else{ + /* 19-digit numbers must be no larger than 9223372036854775807 if positive + ** or 9223372036854775808 if negative. Note that 9223372036854665808 + ** is 2^63. */ + return compare2pow63(zNum)='0' && zNum[0]<='9' ); /* zNum is an unsigned number */ + + if( negFlag ) neg = 1-neg; + while( *zNum=='0' ){ + zNum++; /* Skip leading zeros. Ticket #2454 */ + } + for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); } + if( i<19 ){ + /* Guaranteed to fit if less than 19 digits */ + return 1; + }else if( i>19 ){ + /* Guaranteed to be too big if greater than 19 digits */ + return 0; + }else{ + /* Compare against 2^63. */ + return compare2pow63(zNum)=0 && c<=9; i++){ + v = v*10 + c; + } + + /* The longest decimal representation of a 32 bit integer is 10 digits: + ** + ** 1234567890 + ** 2^31 -> 2147483648 + */ + if( i>10 ){ + return 0; + } + if( v-neg>2147483647 ){ + return 0; + } + if( neg ){ + v = -v; + } + *pValue = (int)v; + return 1; +} + +/* +** The variable-length integer encoding is as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** C = xxxxxxxx 8 bits of data +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** 28 bits - BBBA +** 35 bits - BBBBA +** 42 bits - BBBBBA +** 49 bits - BBBBBBA +** 56 bits - BBBBBBBA +** 64 bits - BBBBBBBBC +*/ + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data write will be between 1 and 9 bytes. The number +** of bytes written is returned. +** +** A variable-length integer consists of the lower 7 bits of each byte +** for all bytes that have the 8th bit set and one byte with the 8th +** bit clear. Except, if we get to the 9th byte, it stores the full +** 8 bits and is the last byte. +*/ +int sqlite3PutVarint(unsigned char *p, u64 v){ + int i, j, n; + u8 buf[10]; + if( v & (((u64)0xff000000)<<32) ){ + p[8] = (u8)v; + v >>= 8; + for(i=7; i>=0; i--){ + p[i] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + } + return 9; + } + n = 0; + do{ + buf[n++] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + }while( v!=0 ); + buf[0] &= 0x7f; + assert( n<=9 ); + for(i=0, j=n-1; j>=0; j--, i++){ + p[i] = buf[j]; + } + return n; +} + +/* +** This routine is a faster version of sqlite3PutVarint() that only +** works for 32-bit positive integers and which is optimized for +** the common case of small integers. A MACRO version, putVarint32, +** is provided which inlines the single-byte case. All code should use +** the MACRO version as this function assumes the single-byte case has +** already been handled. +*/ +int sqlite3PutVarint32(unsigned char *p, u32 v){ +#ifndef putVarint32 + if( (v & ~0x7f)==0 ){ + p[0] = v; + return 1; + } +#endif + if( (v & ~0x3fff)==0 ){ + p[0] = (u8)((v>>7) | 0x80); + p[1] = (u8)(v & 0x7f); + return 2; + } + return sqlite3PutVarint(p, v); +} + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +*/ +u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ + u32 a,b,s; + + a = *p; + /* a: p0 (unmasked) */ + if (!(a&0x80)) + { + *v = a; + return 1; + } + + p++; + b = *p; + /* b: p1 (unmasked) */ + if (!(b&0x80)) + { + a &= 0x7f; + a = a<<7; + a |= b; + *v = a; + return 2; + } + + p++; + a = a<<14; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + a &= (0x7f<<14)|(0x7f); + b &= 0x7f; + b = b<<7; + a |= b; + *v = a; + return 3; + } + + /* CSE1 from below */ + a &= (0x7f<<14)|(0x7f); + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + b &= (0x7f<<14)|(0x7f); + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + *v = a; + return 4; + } + + /* a: p0<<14 | p2 (masked) */ + /* b: p1<<14 | p3 (unmasked) */ + /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + b &= (0x7f<<14)|(0x7f); + s = a; + /* s: p0<<14 | p2 (masked) */ + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* we can skip these cause they were (effectively) done above in calc'ing s */ + /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + /* b &= (0x7f<<14)|(0x7f); */ + b = b<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 5; + } + + /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + s = s<<7; + s |= b; + /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + + p++; + b = b<<14; + b |= *p; + /* b: p1<<28 | p3<<14 | p5 (unmasked) */ + if (!(b&0x80)) + { + /* we can skip this cause it was (effectively) done above in calc'ing s */ + /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + a &= (0x7f<<14)|(0x7f); + a = a<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 6; + } + + p++; + a = a<<14; + a |= *p; + /* a: p2<<28 | p4<<14 | p6 (unmasked) */ + if (!(a&0x80)) + { + a &= (0x1f<<28)|(0x7f<<14)|(0x7f); + b &= (0x7f<<14)|(0x7f); + b = b<<7; + a |= b; + s = s>>11; + *v = ((u64)s)<<32 | a; + return 7; + } + + /* CSE2 from below */ + a &= (0x7f<<14)|(0x7f); + p++; + b = b<<14; + b |= *p; + /* b: p3<<28 | p5<<14 | p7 (unmasked) */ + if (!(b&0x80)) + { + b &= (0x1f<<28)|(0x7f<<14)|(0x7f); + /* moved CSE2 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + s = s>>4; + *v = ((u64)s)<<32 | a; + return 8; + } + + p++; + a = a<<15; + a |= *p; + /* a: p4<<29 | p6<<15 | p8 (unmasked) */ + + /* moved CSE2 up */ + /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ + b &= (0x7f<<14)|(0x7f); + b = b<<8; + a |= b; + + s = s<<4; + b = p[-4]; + b &= 0x7f; + b = b>>3; + s |= b; + + *v = ((u64)s)<<32 | a; + + return 9; +} + +/* +** Read a 32-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +** +** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned +** integer, then set *v to 0xffffffff. +** +** A MACRO version, getVarint32, is provided which inlines the +** single-byte case. All code should use the MACRO version as +** this function assumes the single-byte case has already been handled. +*/ +u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ + u32 a,b; + + /* The 1-byte case. Overwhelmingly the most common. Handled inline + ** by the getVarin32() macro */ + a = *p; + /* a: p0 (unmasked) */ +#ifndef getVarint32 + if (!(a&0x80)) + { + /* Values between 0 and 127 */ + *v = a; + return 1; + } +#endif + + /* The 2-byte case */ + p++; + b = *p; + /* b: p1 (unmasked) */ + if (!(b&0x80)) + { + /* Values between 128 and 16383 */ + a &= 0x7f; + a = a<<7; + *v = a | b; + return 2; + } + + /* The 3-byte case */ + p++; + a = a<<14; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + /* Values between 16384 and 2097151 */ + a &= (0x7f<<14)|(0x7f); + b &= 0x7f; + b = b<<7; + *v = a | b; + return 3; + } + + /* A 32-bit varint is used to store size information in btrees. + ** Objects are rarely larger than 2MiB limit of a 3-byte varint. + ** A 3-byte varint is sufficient, for example, to record the size + ** of a 1048569-byte BLOB or string. + ** + ** We only unroll the first 1-, 2-, and 3- byte cases. The very + ** rare larger cases can be handled by the slower 64-bit varint + ** routine. + */ +#if 1 + { + u64 v64; + u8 n; + + p -= 2; + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ + *v = (u32)v64; + } + return n; + } + +#else + /* For following code (kept for historical record only) shows an + ** unrolling for the 3- and 4-byte varint cases. This code is + ** slightly faster, but it is also larger and much harder to test. + */ + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + /* Values between 2097152 and 268435455 */ + b &= (0x7f<<14)|(0x7f); + a &= (0x7f<<14)|(0x7f); + a = a<<7; + *v = a | b; + return 4; + } + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* Walues between 268435456 and 34359738367 */ + a &= (0x1f<<28)|(0x7f<<14)|(0x7f); + b &= (0x1f<<28)|(0x7f<<14)|(0x7f); + b = b<<7; + *v = a | b; + return 5; + } + + /* We can only reach this point when reading a corrupt database + ** file. In that case we are not in any hurry. Use the (relatively + ** slow) general-purpose sqlite3GetVarint() routine to extract the + ** value. */ + { + u64 v64; + u8 n; + + p -= 4; + n = sqlite3GetVarint(p, &v64); + assert( n>5 && n<=9 ); + *v = (u32)v64; + return n; + } +#endif +} + +/* +** Return the number of bytes that will be needed to store the given +** 64-bit integer. +*/ +int sqlite3VarintLen(u64 v){ + int i = 0; + do{ + i++; + v >>= 7; + }while( v!=0 && ALWAYS(i<9) ); + return i; +} + + +/* +** Read or write a four-byte big-endian integer value. +*/ +u32 sqlite3Get4byte(const u8 *p){ + return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; +} +void sqlite3Put4byte(unsigned char *p, u32 v){ + p[0] = (u8)(v>>24); + p[1] = (u8)(v>>16); + p[2] = (u8)(v>>8); + p[3] = (u8)v; +} + + + +#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +static u8 hexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} +#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ + +#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) +/* +** Convert a BLOB literal of the form "x'hhhhhh'" into its binary +** value. Return a pointer to its binary value. Space to hold the +** binary value has been obtained from malloc and must be freed by +** the calling routine. +*/ +void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ + char *zBlob; + int i; + + zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1); + n--; + if( zBlob ){ + for(i=0; imagic is not a valid open value, take care not +** to modify the db structure at all. It could be that db is a stale +** pointer. In other words, it could be that there has been a prior +** call to sqlite3_close(db) and db has been deallocated. And we do +** not want to write into deallocated memory. +*/ +#ifdef SQLITE_DEBUG +int sqlite3SafetyOn(sqlite3 *db){ + if( db->magic==SQLITE_MAGIC_OPEN ){ + db->magic = SQLITE_MAGIC_BUSY; + assert( sqlite3_mutex_held(db->mutex) ); + return 0; + }else if( db->magic==SQLITE_MAGIC_BUSY ){ + db->magic = SQLITE_MAGIC_ERROR; + db->u1.isInterrupted = 1; + } + return 1; +} +#endif + +/* +** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN. +** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY +** when this routine is called. +*/ +#ifdef SQLITE_DEBUG +int sqlite3SafetyOff(sqlite3 *db){ + if( db->magic==SQLITE_MAGIC_BUSY ){ + db->magic = SQLITE_MAGIC_OPEN; + assert( sqlite3_mutex_held(db->mutex) ); + return 0; + }else{ + db->magic = SQLITE_MAGIC_ERROR; + db->u1.isInterrupted = 1; + return 1; + } +} +#endif + +/* +** Check to make sure we have a valid db pointer. This test is not +** foolproof but it does provide some measure of protection against +** misuse of the interface such as passing in db pointers that are +** NULL or which have been previously closed. If this routine returns +** 1 it means that the db pointer is valid and 0 if it should not be +** dereferenced for any reason. The calling function should invoke +** SQLITE_MISUSE immediately. +** +** sqlite3SafetyCheckOk() requires that the db pointer be valid for +** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to +** open properly and is not fit for general use but which can be +** used as an argument to sqlite3_errmsg() or sqlite3_close(). +*/ +int sqlite3SafetyCheckOk(sqlite3 *db){ + u32 magic; + if( db==0 ) return 0; + magic = db->magic; + if( magic!=SQLITE_MAGIC_OPEN +#ifdef SQLITE_DEBUG + && magic!=SQLITE_MAGIC_BUSY +#endif + ){ + return 0; + }else{ + return 1; + } +} +int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ + u32 magic; + magic = db->magic; + if( magic!=SQLITE_MAGIC_SICK && + magic!=SQLITE_MAGIC_OPEN && + magic!=SQLITE_MAGIC_BUSY ) return 0; + return 1; +} From e025d1d7e51f20eca45730c0a54066eaa3336b15 Mon Sep 17 00:00:00 2001 From: shane Date: Mon, 7 Sep 2009 03:48:52 +0000 Subject: [PATCH 3/4] Attempt to handle numbers at the limits of the IEEE 754 range better (nan.test now passes). FossilOrigin-Name: 2a74ae1969aeec93576a44e11177677e6f3cea9c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 26 +++++++++++++++++++------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index d97af3eed7..aa0928931a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sinternal\sAtoF\sto\simprove\s"accuracy"\swhen\smeasured\sagainst\sbuilt-in\sGCC\satof(). -D 2009-09-07T02:46:32 +C Attempt\sto\shandle\snumbers\sat\sthe\slimits\sof\sthe\sIEEE\s754\srange\sbetter\s(nan.test\snow\spasses). +D 2009-09-07T03:48:53 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -203,7 +203,7 @@ F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b F src/trigger.c 8158237fc5fa4b51a126a294791729c64d27a0a9 F src/update.c 12ffd68c2f241c730d5e051eb29b23e90682ff8a F src/utf.c 3ca2c9461b8e942c68da28bfccd448663f536a6f -F src/util.c 7404ac078125aafc0e274b2d1a918c3f15b50294 +F src/util.c 59d4e9456bf1fe581f415a783fa0cee6115c8f35 F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0 F src/vdbe.c addf5f6fefe9b9c6ca8819efbf52cfce8bd68089 F src/vdbe.h 080fe6bc1264438becb8bf9b9f3c84074c336b78 @@ -750,7 +750,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2aeab80e5b84f5e94c5c99b4adeca805601c844b -R 0b92cbb9074dfe690c0e4c14e6998bde +P 438e1577d0f9ceb2851ee0df0df18f0229eca491 +R c2daf7f44258efdd4b9472e2943bb165 U shane -Z 82d0c356acbda85944f3ae28efe12d94 +Z 2480ce6a3608c9caf8089d33acaa4dae diff --git a/manifest.uuid b/manifest.uuid index fb0b520154..9dcb56fba4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -438e1577d0f9ceb2851ee0df0df18f0229eca491 \ No newline at end of file +2a74ae1969aeec93576a44e11177677e6f3cea9c \ No newline at end of file diff --git a/src/util.c b/src/util.c index 085d7140e4..d12bcd5360 100644 --- a/src/util.c +++ b/src/util.c @@ -375,14 +375,26 @@ int sqlite3AtoF(const char *z, double *pResult){ ** and store in result. */ if( e ){ double scale = 1.0; - /* 1.0e+22 is the largest power of 10 than can be - ** represented exactly. */ - while( e%22 ) { scale *= 1.0e+1; e -= 1; } - while( e>0 ) { scale *= 1.0e+22; e -= 22; } - if( esign<0 ){ - result = s / scale; + /* attempt to handle extremely small/large numbers better */ + if( e>307 && e<342 ){ + while( e%308 ) { scale *= 1.0e+1; e -= 1; } + if( esign<0 ){ + result = s / scale; + result /= 1.0e+308; + }else{ + result = s * scale; + result *= 1.0e+308; + } }else{ - result = s * scale; + /* 1.0e+22 is the largest power of 10 than can be + ** represented exactly. */ + while( e%22 ) { scale *= 1.0e+1; e -= 1; } + while( e>0 ) { scale *= 1.0e+22; e -= 22; } + if( esign<0 ){ + result = s / scale; + }else{ + result = s * scale; + } } } else { result = (double)s; From cea72b2dc2f4fc9b3ebba2649da210a272536201 Mon Sep 17 00:00:00 2001 From: shane Date: Mon, 7 Sep 2009 04:38:36 +0000 Subject: [PATCH 4/4] Warning cleanup from the MSVC compile. FossilOrigin-Name: 26cd015c0ee1c18dd37f11b47ce35cfa320b3514 --- manifest | 32 ++++++++++++++++---------------- manifest.uuid | 2 +- src/analyze.c | 8 +++++--- src/callback.c | 2 +- src/main.c | 10 +++++----- src/resolve.c | 2 +- src/sqliteInt.h | 4 ++-- src/trigger.c | 4 +++- src/update.c | 2 +- src/utf.c | 2 +- src/vdbe.c | 2 +- src/vdbeaux.c | 2 ++ src/where.c | 2 +- 13 files changed, 40 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index aa0928931a..04ad70f01f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\shandle\snumbers\sat\sthe\slimits\sof\sthe\sIEEE\s754\srange\sbetter\s(nan.test\snow\spasses). -D 2009-09-07T03:48:53 +C Warning\scleanup\sfrom\sthe\sMSVC\scompile. +D 2009-09-07T04:38:36 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -100,7 +100,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c 55b601857d924e07c91cfa69e9b2cb5093498c93 -F src/analyze.c 4584556d374fe3ab791be9be32ada7713fdced52 +F src/analyze.c 5a8b8aa3d170eac5e71af45458cec61f83c623ee F src/attach.c 13995348fc5a26cdd136a50806faf292aabc173f F src/auth.c 4cfb8fae12656cca2739176abebab84ed79dd8f6 F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3 @@ -110,7 +110,7 @@ F src/btree.c 6b60ece56141bbe23aa6efca10f1612d34271c2f F src/btree.h 577448a890c2ab9b21e6ab74f073526184bceebe F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705 F src/build.c df8dfff696329c192240e3d532f9dad0ef5abace -F src/callback.c 9bc0ae998f15207d3115224979331c0aafc9bcc3 +F src/callback.c f49c305dc94b78da948953c392963929c0e70f9b F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0 F src/date.c ab5f7137656652a48434d64f96bdcdc823bb23b3 F src/delete.c 6b95963dabd558d45385e9b5be1fb4aa7ba7fa62 @@ -126,7 +126,7 @@ F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0 F src/legacy.c 303b4ffcf1ae652fcf5ef635846c563c254564f6 F src/lempar.c 0c4d1ab0a5ef2b0381eb81a732c54f68f27a574d F src/loadext.c 0e88a335665db0b2fb4cece3e49dcb65d832635a -F src/main.c 572da463c5616ff8d1e1c5df4bb7566085b52b7c +F src/main.c 6688d56c2437eed4a8bbbb2fd517c59ff927f337 F src/malloc.c b1725183bcc4ce2e569f1b65da844dc3e4c7a643 F src/mem0.c f2f84062d1f35814d6535c9f9e33de3bfb3b132c F src/mem1.c e6d5c23941288df8191b8a98c28e3f57771e2270 @@ -157,13 +157,13 @@ F src/pragma.c 0a3b3141935dbea48575af8131d0fd2c1efe9b06 F src/prepare.c 9803fc01f0db29ac4a17fa662902af285f37c06b F src/printf.c 508a1c59433353552b6553cba175eaa7331f8fc1 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628 -F src/resolve.c e78029b04dd811e4e0b7be6c51e7c31accc024b6 +F src/resolve.c 941843301f6fda6c6350839c6955a172441a0782 F src/rowset.c c64dafba1f9fd876836c8db8682966b9d197eb1f F src/select.c 8bc7347fe88cf16ac2cb1a37fb918d1417ab4142 F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb F src/sqlite.h.in 94052f827890de6fb7c913b95507076909261d9b F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 -F src/sqliteInt.h 12f2e4a8aa97c5ae9a83b8189d1280c84922cbfd +F src/sqliteInt.h 0abbf6e260e19e41f1d57dbf02b1283f77cce81a F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d @@ -200,21 +200,21 @@ F src/test_tclvar.c 9e42fa59d3d2f064b7ab8628e7ab2dc8a9fe93d4 F src/test_thread.c b8a1ab7ca1a632f18e8a361880d5d65eeea08eac F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241 F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b -F src/trigger.c 8158237fc5fa4b51a126a294791729c64d27a0a9 -F src/update.c 12ffd68c2f241c730d5e051eb29b23e90682ff8a -F src/utf.c 3ca2c9461b8e942c68da28bfccd448663f536a6f +F src/trigger.c 55cdf9d595ded7f5843e5ac021722c19fe0451fa +F src/update.c 3e97974baa914f32d4ae690fa0cb7281aff8cd39 +F src/utf.c 99cf927eabb104621ba889ac0dd075fc1657ad30 F src/util.c 59d4e9456bf1fe581f415a783fa0cee6115c8f35 F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0 -F src/vdbe.c addf5f6fefe9b9c6ca8819efbf52cfce8bd68089 +F src/vdbe.c a158f0f3efbf2a66037dbfe4024398719cf61596 F src/vdbe.h 080fe6bc1264438becb8bf9b9f3c84074c336b78 F src/vdbeInt.h 6094e60f64d7a9d4352d4e6b90d1219dce947ad9 F src/vdbeapi.c 8d5013ab6104be757c208a70ffb191cc27d2b688 -F src/vdbeaux.c a88ef864f13ed698a267bcec29af22fbcd727f82 +F src/vdbeaux.c f13f4bc61c96837ee1ac531ee2401b6181244886 F src/vdbeblob.c f93cb60ac388633ed3bde8a94ef161ad2dbfb689 F src/vdbemem.c dc551981833756ea34a3e0b238f759479e7cf526 F src/vtab.c 3e54fe39374e5feb8b174de32a90e7a21966025d F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04 -F src/where.c a3218dfcf32e3d933270b76a72b97065f24b3f2c +F src/where.c 15b38ff11d83f749ac61ef2ab5ad7ddbee273d69 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45 @@ -750,7 +750,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 438e1577d0f9ceb2851ee0df0df18f0229eca491 -R c2daf7f44258efdd4b9472e2943bb165 +P 2a74ae1969aeec93576a44e11177677e6f3cea9c +R 8cf719dccba8f130bf794b448e1f87bd U shane -Z 2480ce6a3608c9caf8089d33acaa4dae +Z 6418a3cacb4f862c4527545d609ab4e2 diff --git a/manifest.uuid b/manifest.uuid index 9dcb56fba4..7de8f3f009 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a74ae1969aeec93576a44e11177677e6f3cea9c \ No newline at end of file +26cd015c0ee1c18dd37f11b47ce35cfa320b3514 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 273856d0af..01b4ad44b9 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -49,7 +49,7 @@ static void openStatTable( }; int aRoot[] = {0, 0}; - int aCreateTbl[] = {0, 0}; + u8 aCreateTbl[] = {0, 0}; int i; sqlite3 *db = pParse->db; @@ -506,6 +506,8 @@ void sqlite3DeleteIndexSamples(Index *pIdx){ sqlite3DbFree(dbMem, pIdx->aSample); pIdx->aSample = 0; } +#else + UNUSED_PARAMETER(pIdx); #endif } @@ -609,7 +611,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ assert( pIdx->aSample ); { IndexSample *pSample = &pIdx->aSample[iSample]; - pSample->eType = eType; + pSample->eType = (u8)eType; if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ pSample->u.r = sqlite3_column_double(pStmt, 2); }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ @@ -622,7 +624,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ if( n>24 ){ n = 24; } - pSample->nByte = n; + pSample->nByte = (u8)n; pSample->u.z = sqlite3DbMallocRaw(dbMem, n); if( pSample->u.z ){ memcpy(pSample->u.z, z, n); diff --git a/src/callback.c b/src/callback.c index 0d4f9dd15f..492e4206f9 100644 --- a/src/callback.c +++ b/src/callback.c @@ -83,7 +83,7 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ */ CollSeq *sqlite3GetCollSeq( sqlite3* db, /* The database connection */ - int enc, /* The desired encoding for the collating sequence */ + u8 enc, /* The desired encoding for the collating sequence */ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ const char *zName /* Collating sequence name */ ){ diff --git a/src/main.c b/src/main.c index 9bc46190fd..e4324e7484 100644 --- a/src/main.c +++ b/src/main.c @@ -1359,8 +1359,8 @@ int sqlite3_extended_errcode(sqlite3 *db){ static int createCollation( sqlite3* db, const char *zName, - int enc, - int collType, + u8 enc, + u8 collType, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) @@ -1808,7 +1808,7 @@ int sqlite3_create_collation( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, enc, SQLITE_COLL_USER, pCtx, xCompare, 0); + rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -1828,7 +1828,7 @@ int sqlite3_create_collation_v2( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, enc, SQLITE_COLL_USER, pCtx, xCompare, xDel); + rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -1851,7 +1851,7 @@ int sqlite3_create_collation16( assert( !db->mallocFailed ); zName8 = sqlite3Utf16to8(db, zName, -1); if( zName8 ){ - rc = createCollation(db, zName8, enc, SQLITE_COLL_USER, pCtx, xCompare, 0); + rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); sqlite3DbFree(db, zName8); } rc = sqlite3ApiExit(db, rc); diff --git a/src/resolve.c b/src/resolve.c index 857b67d813..4090bdd6ec 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -261,7 +261,7 @@ static int lookupName( testcase( iCol==32 ); pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<iColumn = iCol; + pExpr->iColumn = (i16)iCol; pExpr->pTab = pTab; isTrigger = 1; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a8a1da6782..c77721ba26 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2805,7 +2805,7 @@ void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(sqlite3 *); char *sqlite3Utf16to8(sqlite3 *, const void*, int); #ifdef SQLITE_ENABLE_STAT2 -char *sqlite3Utf8to16(sqlite3 *, int, char *, int, int *); +char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *); #endif int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); @@ -2831,7 +2831,7 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); -CollSeq *sqlite3GetCollSeq(sqlite3*, int, CollSeq *, const char*); +CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*); char sqlite3AffinityType(const char*); void sqlite3Analyze(Parse*, Token*, Token*); int sqlite3InvokeBusyHandler(BusyHandler*); diff --git a/src/trigger.c b/src/trigger.c index e17b48e742..00acc813e2 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -695,7 +695,7 @@ static int codeTriggerProgram( ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy */ - pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:orconf; + pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; switch( pStep->op ){ case TK_UPDATE: { @@ -955,6 +955,8 @@ void sqlite3CodeRowTrigger( ){ Trigger *p; + UNUSED_PARAMETER(newIdx); + assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER ); diff --git a/src/update.c b/src/update.c index 8015b04cc4..ba1ad91f2c 100644 --- a/src/update.c +++ b/src/update.c @@ -127,7 +127,7 @@ void sqlite3Update( int regOldRowid; /* The old rowid */ int regNewRowid; /* The new rowid */ int regNew; - int regOld; + int regOld = 0; int regRowSet = 0; /* Rowset of rows to be updated */ int regRec; /* Register used for new table record to insert */ diff --git a/src/utf.c b/src/utf.c index 159ac90b90..c3d07be828 100644 --- a/src/utf.c +++ b/src/utf.c @@ -465,7 +465,7 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){ ** flag set. */ #ifdef SQLITE_ENABLE_STAT2 -char *sqlite3Utf8to16(sqlite3 *db, int enc, char *z, int n, int *pnOut){ +char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){ Mem m; memset(&m, 0, sizeof(m)); m.db = db; diff --git a/src/vdbe.c b/src/vdbe.c index e6b325abc1..dd2ff7b9f5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4863,7 +4863,7 @@ case OP_Program: { /* jump */ p->pFrame = pFrame; p->aMem = &VdbeFrameMem(pFrame)[-1]; p->nMem = pFrame->nChildMem; - p->nCursor = pFrame->nChildCsr; + p->nCursor = (u16)pFrame->nChildCsr; p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1]; p->aOp = pProgram->aOp; p->nOp = pProgram->nOp; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 546c16fe9b..efbf6b15d8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2761,6 +2761,8 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ u32 lenRowid; /* Size of the rowid */ Mem m, v; + UNUSED_PARAMETER(db); + /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption. ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so diff --git a/src/where.c b/src/where.c index f23133b57e..9859ab5587 100644 --- a/src/where.c +++ b/src/where.c @@ -2357,7 +2357,7 @@ static void bestBtreeIndex( nRow = (double)(aiRowEst[nEq] * nInMul); if( bInEst && nRow*2>aiRowEst[0] ){ nRow = aiRowEst[0]/2; - nInMul = nRow / aiRowEst[nEq]; + nInMul = (int)(nRow / aiRowEst[nEq]); } /* Assume constant cost to access a row and logarithmic cost to