# # # add_file "sqlite/os_os2.c" # content [123cb394c069bc8c6a305830ffa2bc5f72e5b83a] # # add_file "sqlite/os_os2.h" # content [e5f17dd69333632bbc3112881ea407c37d245eb3] # # patch "ChangeLog" # from [7a0eb7f7c256403027c14a0e578ca26b19c036e2] # to [73525808bf250d9d6cdedb1b0762c00940ac0680] # # patch "Makefile.am" # from [3c8a4501c0b6a6823dd877796008968e06d23199] # to [0cd884200807c9d0794a74633c3283df45da028f] # # patch "configure.ac" # from [824721ae0b37ed846b0240a912e197eb69d4bd23] # to [3faced834db143b4501acf74123f70fef37148df] # # patch "sqlite/attach.c" # from [514f90623c891143846625afcab409d6b4986565] # to [27a31d3b89d7ebb5b358847607b1ec795384123c] # # patch "sqlite/build.c" # from [be0629119df8c1e09050a8fcbf182112f00e3b14] # to [eefefdc88cb342bc0f7cb41ccdf3930739ab50e9] # # patch "sqlite/callback.c" # from [d8c5ab1cd6f3b7182b2ee63bf53f1b69c0f74306] # to [fd9bb39f7ff6b52bad8365617abc61c720640429] # # patch "sqlite/expr.c" # from [c85d7bee7d8e3184e00166c2c2ab6edd57b60486] # to [f1ad18d0b7bb3abbf09cb30871ae6e7618447bc5] # # patch "sqlite/func.c" # from [380f2f8e555ccbf899e65f01475c4ac13c478dc2] # to [acbbf533b55221f26760798d99b37de3ac5678fe] # # patch "sqlite/main.c" # from [5cdd81aaf159836b5ca277192da4f7461fd15078] # to [928d93cfd5d72be3a619ee908182c9432151a99e] # # patch "sqlite/os.h" # from [93035a0e3b9dd05cdd0aaef32ea28ca28e02fe78] # to [46fad85c707ad8643622bab9d894a642940850aa] # # patch "sqlite/os_unix.c" # from [35ad4d81c90800f509d28580742b67906d289223] # to [17d91581a0ab478a06cb6f257b707a4c4a93e5a7] # # patch "sqlite/os_win.c" # from [8ced9ac82670bbf77492961a2f7ff80a87f1404f] # to [c6976ae50b61fb5b7dce399e578aa1865f02b84f] # # patch "sqlite/pager.c" # from [33186636a07eeaf34028083c32b27b9647556be7] # to [ddd05666bb89808a516baef2c186d6a75887ae90] # # patch "sqlite/parse.c" # from [99da8c67793c0a37e0f1e5349be63339ca7061a6] # to [7edb838b64d4361c1b52c1b6b0e7ab0ce64e0695] # # patch "sqlite/prepare.c" # from [6afd730cc8851c0920b5f9050294646b1c2ab28c] # to [bbf12d3147116b284b157232efaef3bbe5df08fc] # # patch "sqlite/printf.c" # from [358b4b585270f92a228e646e7bbb261c65f2a166] # to [7029e5f7344a478394a02c52837ff296ee1ab240] # # patch "sqlite/select.c" # from [ca8ee9b54a52e31c22c23ae5264d323f723d253b] # to [8daba07a04a6d41f5267ea8353324cbe5a210e14] # # patch "sqlite/sqlite3.h" # from [8fce4dddf986e8bca2236a84423b2ba4a4ff4bd1] # to [de25268fd9fbc74cf0a7c2e07d455e022cc27daf] # # patch "sqlite/sqliteInt.h" # from [9052a26e0467be0ac0c554fb1f8de671eda2ea0d] # to [96bd4e89dc78164647382890e39aae0e7e05c9d6] # # patch "sqlite/utf.c" # from [1d51225bce1ea8d1978e8ab28e862a0c12c7a8e8] # to [ab81ac59084ff1c07d421eb1a0a84ec809603b44] # # patch "sqlite/util.c" # from [137e6765825863593095cbbeab0e9e4ba1cf575d] # to [ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d] # # patch "sqlite/vdbe.c" # from [a56ef5de6d91aedf6f1f0db03c65aa01ecbe11ba] # to [a4c970bd74a5af20bf4627f704a634ceff8ff68d] # # patch "sqlite/where.c" # from [1ba8eb02aba7eb8b75d7be0635200a14f0bef73a] # to [06ec443109d8aec7be6d491ef31f72bc08af2c75] # ============================================================ --- sqlite/os_os2.c 123cb394c069bc8c6a305830ffa2bc5f72e5b83a +++ sqlite/os_os2.c 123cb394c069bc8c6a305830ffa2bc5f72e5b83a @@ -0,0 +1,965 @@ +/* +** 2006 Feb 14 +** +** 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 that is specific to OS/2. +*/ +#include "sqliteInt.h" +#include "os.h" + +#if OS_OS2 + +/* +** Macros used to determine whether or not to use threads. +*/ +#if defined(THREADSAFE) && THREADSAFE +# define SQLITE_OS2_THREADS 1 +#endif + +/* +** Include code that is common to all os_*.c files +*/ +#include "os_common.h" + +/* +** The os2File structure is subclass of OsFile specific for the OS/2 +** protability layer. +*/ +typedef struct os2File os2File; +struct os2File { + IoMethod const *pMethod; /* Always the first entry */ + HFILE h; /* Handle for accessing the file */ + int delOnClose; /* True if file is to be deleted on close */ + char* pathToDel; /* Name of file to delete on close */ + unsigned char locktype; /* Type of lock currently held on this file */ +}; + +/* +** Do not include any of the File I/O interface procedures if the +** SQLITE_OMIT_DISKIO macro is defined (indicating that there database +** will be in-memory only) +*/ +#ifndef SQLITE_OMIT_DISKIO + +/* +** Delete the named file +*/ +int sqlite3Os2Delete( const char *zFilename ){ + DosDelete( (PSZ)zFilename ); + TRACE2( "DELETE \"%s\"\n", zFilename ); + return SQLITE_OK; +} + +/* +** Return TRUE if the named file exists. +*/ +int sqlite3Os2FileExists( const char *zFilename ){ + FILESTATUS3 fsts3ConfigInfo; + memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); + return DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD, + &fsts3ConfigInfo, sizeof(FILESTATUS3) ) == NO_ERROR; +} + +/* Forward declaration */ +int allocateOs2File( os2File *pInit, OsFile **pld ); + +/* +** Attempt to open a file for both reading and writing. If that +** fails, try opening it read-only. If the file does not exist, +** try to create it. +** +** On success, a handle for the open file is written to *id +** and *pReadonly is set to 0 if the file was opened for reading and +** writing or 1 if the file was opened read-only. The function returns +** SQLITE_OK. +** +** On failure, the function returns SQLITE_CANTOPEN and leaves +** *id and *pReadonly unchanged. +*/ +int sqlite3Os2OpenReadWrite( + const char *zFilename, + OsFile **pld, + int *pReadonly +){ + os2File f; + HFILE hf; + ULONG ulAction; + APIRET rc; + + assert( *pld == 0 ); + rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, + FILE_ARCHIVED | FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | + OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL ); + if( rc != NO_ERROR ){ + rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, + FILE_ARCHIVED | FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | + OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL ); + if( rc != NO_ERROR ){ + return SQLITE_CANTOPEN; + } + *pReadonly = 1; + } + else{ + *pReadonly = 0; + } + f.h = hf; + f.locktype = NO_LOCK; + f.delOnClose = 0; + f.pathToDel = NULL; + OpenCounter(+1); + TRACE3( "OPEN R/W %d \"%s\"\n", hf, zFilename ); + return allocateOs2File( &f, pld ); +} + + +/* +** Attempt to open a new file for exclusive access by this process. +** The file will be opened for both reading and writing. To avoid +** a potential security problem, we do not allow the file to have +** previously existed. Nor do we allow the file to be a symbolic +** link. +** +** If delFlag is true, then make arrangements to automatically delete +** the file when it is closed. +** +** On success, write the file handle into *id and return SQLITE_OK. +** +** On failure, return SQLITE_CANTOPEN. +*/ +int sqlite3Os2OpenExclusive( const char *zFilename, OsFile **pld, int delFlag ){ + os2File f; + HFILE hf; + ULONG ulAction; + APIRET rc; + + assert( *pld == 0 ); + rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS, + OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | + OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL ); + if( rc != NO_ERROR ){ + return SQLITE_CANTOPEN; + } + + f.h = hf; + f.locktype = NO_LOCK; + f.delOnClose = delFlag ? 1 : 0; + f.pathToDel = delFlag ? sqlite3OsFullPathname( zFilename ) : NULL; + OpenCounter( +1 ); + if( delFlag ) DosForceDelete( sqlite3OsFullPathname( zFilename ) ); + TRACE3( "OPEN EX %d \"%s\"\n", hf, sqlite3OsFullPathname ( zFilename ) ); + return allocateOs2File( &f, pld ); +} + +/* +** Attempt to open a new file for read-only access. +** +** On success, write the file handle into *id and return SQLITE_OK. +** +** On failure, return SQLITE_CANTOPEN. +*/ +int sqlite3Os2OpenReadOnly( const char *zFilename, OsFile **pld ){ + os2File f; + HFILE hf; + ULONG ulAction; + APIRET rc; + + assert( *pld == 0 ); + rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, + FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | + OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL ); + if( rc != NO_ERROR ){ + return SQLITE_CANTOPEN; + } + f.h = hf; + f.locktype = NO_LOCK; + f.delOnClose = 0; + f.pathToDel = NULL; + OpenCounter( +1 ); + TRACE3( "OPEN RO %d \"%s\"\n", hf, zFilename ); + return allocateOs2File( &f, pld ); +} + +/* +** Attempt to open a file descriptor for the directory that contains a +** file. This file descriptor can be used to fsync() the directory +** in order to make sure the creation of a new file is actually written +** to disk. +** +** This routine is only meaningful for Unix. It is a no-op under +** OS/2 since OS/2 does not support hard links. +** +** On success, a handle for a previously open file is at *id is +** updated with the new directory file descriptor and SQLITE_OK is +** returned. +** +** On failure, the function returns SQLITE_CANTOPEN and leaves +** *id unchanged. +*/ +int os2OpenDirectory( + OsFile *id, + const char *zDirname +){ + return SQLITE_OK; +} + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** temporary files. +*/ +char *sqlite3_temp_directory = 0; + +/* +** Create a temporary file name in zBuf. zBuf must be big enough to +** hold at least SQLITE_TEMPNAME_SIZE characters. +*/ +int sqlite3Os2TempFileName( char *zBuf ){ + static const unsigned char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + int i, j; + PSZ zTempPath = 0; + if( DosScanEnv( "TEMP", &zTempPath ) ){ + if( DosScanEnv( "TMP", &zTempPath ) ){ + if( DosScanEnv( "TMPDIR", &zTempPath ) ){ + ULONG ulDriveNum = 0, ulDriveMap = 0; + DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); + sprintf( zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) ); + } + } + } + for(;;){ + sprintf( zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath ); + j = strlen( zBuf ); + sqlite3Randomness( 15, &zBuf[j] ); + for( i = 0; i < 15; i++, j++ ){ + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + if( !sqlite3OsFileExists( zBuf ) ) break; + } + TRACE2( "TEMP FILENAME: %s\n", zBuf ); + return SQLITE_OK; +} + +/* +** Close a file. +*/ +int os2Close( OsFile **pld ){ + os2File *pFile; + if( pld && (pFile = (os2File*)*pld)!=0 ){ + TRACE2( "CLOSE %d\n", pFile->h ); + DosClose( pFile->h ); + pFile->locktype = NO_LOCK; + if( pFile->delOnClose != 0 ){ + DosForceDelete( pFile->pathToDel ); + } + *pld = 0; + OpenCounter( -1 ); + } + + return SQLITE_OK; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +int os2Read( OsFile *id, void *pBuf, int amt ){ + ULONG got; + assert( id!=0 ); + SimulateIOError( SQLITE_IOERR ); + TRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); + DosRead( ((os2File*)id)->h, pBuf, amt, &got ); + return (got == (ULONG)amt) ? SQLITE_OK : SQLITE_IOERR; +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +int os2Write( OsFile *id, const void *pBuf, int amt ){ + APIRET rc=NO_ERROR; + ULONG wrote; + assert( id!=0 ); + SimulateIOError( SQLITE_IOERR ); + SimulateDiskfullError; + TRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); + while( amt > 0 && + (rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){ + amt -= wrote; + pBuf = &((char*)pBuf)[wrote]; + } + + return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK; +} + +/* +** Move the read/write pointer in a file. +*/ +int os2Seek( OsFile *id, i64 offset ){ + APIRET rc; + ULONG filePointer = 0L; + assert( id!=0 ); + rc = DosSetFilePtr( ((os2File*)id)->h, offset, FILE_BEGIN, &filePointer ); + TRACE3( "SEEK %d %lld\n", ((os2File*)id)->h, offset ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +} + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +int os2Sync( OsFile *id, int dataOnly ){ + assert( id!=0 ); + TRACE3( "SYNC %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); + return DosResetBuffer( ((os2File*)id)->h ) ? SQLITE_IOERR : SQLITE_OK; +} + +/* +** Sync the directory zDirname. This is a no-op on operating systems other +** than UNIX. +*/ +int sqlite3Os2SyncDirectory( const char *zDirname ){ + SimulateIOError( SQLITE_IOERR ); + return SQLITE_OK; +} + +/* +** Truncate an open file to a specified size +*/ +int os2Truncate( OsFile *id, i64 nByte ){ + APIRET rc; + ULONG upperBits = nByte>>32; + assert( id!=0 ); + TRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte ); + SimulateIOError( SQLITE_IOERR ); + rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits ); + if( rc != NO_ERROR ){ + return SQLITE_IOERR; + } + rc = DosSetFilePtr( ((os2File*)id)->h, 0L, FILE_END, &upperBits ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +} + +/* +** Determine the current size of a file in bytes +*/ +int os2FileSize( OsFile *id, i64 *pSize ){ + APIRET rc; + FILESTATUS3 fsts3FileInfo; + memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo)); + assert( id!=0 ); + SimulateIOError( SQLITE_IOERR ); + rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) ); + if( rc == NO_ERROR ){ + *pSize = fsts3FileInfo.cbFile; + return SQLITE_OK; + } + else{ + return SQLITE_IOERR; + } +} + +/* +** Acquire a reader lock. +*/ +static int getReadLock( os2File *id ){ + FILELOCK LockArea, + UnlockArea; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + LockArea.lOffset = SHARED_FIRST; + LockArea.lRange = SHARED_SIZE; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L ); +} + +/* +** Undo a readlock +*/ +static int unlockReadLock( os2File *id ){ + FILELOCK LockArea, + UnlockArea; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = SHARED_FIRST; + UnlockArea.lRange = SHARED_SIZE; + return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L ); +} + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Check that a given pathname is a directory and is writable +** +*/ +int sqlite3Os2IsDirWritable( char *zDirname ){ + FILESTATUS3 fsts3ConfigInfo; + APIRET rc = NO_ERROR; + memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); + if( zDirname==0 ) return 0; + if( strlen(zDirname)>CCHMAXPATH ) return 0; + rc = DosQueryPathInfo( (PSZ)zDirname, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) ); + if( rc != NO_ERROR ) return 0; + if( (fsts3ConfigInfo.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY ) return 0; + + return 1; +} +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. The os2Unlock() routine +** erases all locks at once and returns us immediately to locking level 0. +** It is not possible to lower the locking level one step at a time. You +** must go straight to locking level 0. +*/ +int os2Lock( OsFile *id, int locktype ){ + APIRET rc = SQLITE_OK; /* Return code from subroutines */ + APIRET res = 1; /* Result of a windows lock call */ + int newLocktype; /* Set id->locktype to this value before exiting */ + int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ + FILELOCK LockArea, + UnlockArea; + os2File *pFile = (os2File*)id; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + assert( pFile!=0 ); + TRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ); + + /* If there is already a lock of this type or more restrictive on the + ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** sqlite3OsEnterMutex() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or + ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of + ** the PENDING_LOCK byte is temporary. + */ + newLocktype = pFile->locktype; + if( pFile->locktype==NO_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) + ){ + int cnt = 3; + + LockArea.lOffset = PENDING_BYTE; + LockArea.lRange = 1L; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + + while( cnt-->0 && (res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L) )!=NO_ERROR ){ + /* Try 3 times to get the pending lock. The pending lock might be + ** held by another reader process who will release it momentarily. + */ + TRACE2( "could not get a PENDING lock. cnt=%d\n", cnt ); + DosSleep(1); + } + gotPendingLock = res; + } + + /* Acquire a shared lock + */ + if( locktype==SHARED_LOCK && res ){ + assert( pFile->locktype==NO_LOCK ); + res = getReadLock(pFile); + if( res == NO_ERROR ){ + newLocktype = SHARED_LOCK; + } + } + + /* Acquire a RESERVED lock + */ + if( locktype==RESERVED_LOCK && res ){ + assert( pFile->locktype==SHARED_LOCK ); + LockArea.lOffset = RESERVED_BYTE; + LockArea.lRange = 1L; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + if( res == NO_ERROR ){ + newLocktype = RESERVED_LOCK; + } + } + + /* Acquire a PENDING lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + newLocktype = PENDING_LOCK; + gotPendingLock = 0; + } + + /* Acquire an EXCLUSIVE lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + assert( pFile->locktype>=SHARED_LOCK ); + res = unlockReadLock(pFile); + TRACE2( "unreadlock = %d\n", res ); + LockArea.lOffset = SHARED_FIRST; + LockArea.lRange = SHARED_SIZE; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + if( res == NO_ERROR ){ + newLocktype = EXCLUSIVE_LOCK; + }else{ + TRACE2( "error-code = %d\n", res ); + } + } + + /* If we are holding a PENDING lock that ought to be released, then + ** release it now. + */ + if( gotPendingLock && locktype==SHARED_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = PENDING_BYTE; + UnlockArea.lRange = 1L; + DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + } + + /* Update the state of the lock has held in the file descriptor then + ** return the appropriate result code. + */ + if( res == NO_ERROR ){ + rc = SQLITE_OK; + }else{ + TRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, + locktype, newLocktype ); + rc = SQLITE_BUSY; + } + pFile->locktype = newLocktype; + return rc; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero, otherwise zero. +*/ +int os2CheckReservedLock( OsFile *id ){ + APIRET rc; + os2File *pFile = (os2File*)id; + assert( pFile!=0 ); + if( pFile->locktype>=RESERVED_LOCK ){ + rc = 1; + TRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, rc ); + }else{ + FILELOCK LockArea, + UnlockArea; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + LockArea.lOffset = RESERVED_BYTE; + LockArea.lRange = 1L; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + if( rc == NO_ERROR ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = RESERVED_BYTE; + UnlockArea.lRange = 1L; + rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + } + TRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, rc ); + } + return rc; +} + +/* +** Lower the locking level on file descriptor id to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** It is not possible for this routine to fail if the second argument +** is NO_LOCK. If the second argument is SHARED_LOCK then this routine +** might return SQLITE_IOERR; +*/ +int os2Unlock( OsFile *id, int locktype ){ + int type; + APIRET rc = SQLITE_OK; + os2File *pFile = (os2File*)id; + FILELOCK LockArea, + UnlockArea; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + assert( pFile!=0 ); + assert( locktype<=SHARED_LOCK ); + TRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype ); + type = pFile->locktype; + if( type>=EXCLUSIVE_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = SHARED_FIRST; + UnlockArea.lRange = SHARED_SIZE; + DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){ + /* This should never happen. We should always be able to + ** reacquire the read lock */ + rc = SQLITE_IOERR; + } + } + if( type>=RESERVED_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = RESERVED_BYTE; + UnlockArea.lRange = 1L; + DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + } + if( locktype==NO_LOCK && type>=SHARED_LOCK ){ + unlockReadLock(pFile); + } + if( type>=PENDING_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = PENDING_BYTE; + UnlockArea.lRange = 1L; + DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + } + pFile->locktype = locktype; + return rc; +} + +/* +** Turn a relative pathname into a full pathname. Return a pointer +** to the full pathname stored in space obtained from sqliteMalloc(). +** The calling function is responsible for freeing this space once it +** is no longer needed. +*/ +char *sqlite3Os2FullPathname( const char *zRelative ){ + char *zFull = 0; + if( strchr(zRelative, ':') ){ + sqlite3SetString( &zFull, zRelative, (char*)0 ); + }else{ + char zBuff[SQLITE_TEMPNAME_SIZE - 2] = {0}; + char zDrive[1] = {0}; + ULONG cbzFullLen = SQLITE_TEMPNAME_SIZE; + ULONG ulDriveNum = 0; + ULONG ulDriveMap = 0; + DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); + DosQueryCurrentDir( 0L, zBuff, &cbzFullLen ); + zFull = sqliteMalloc( cbzFullLen ); + sprintf( zDrive, "%c", (char)('A' + ulDriveNum - 1) ); + sqlite3SetString( &zFull, zDrive, ":\\", zBuff, "\\", zRelative, (char*)0 ); + } + return zFull; +} + +/* +** The fullSync option is meaningless on os2, or correct me if I'm wrong. This is a no-op. +** From os_unix.c: Change the value of the fullsync flag in the given file descriptor. +** From os_unix.c: ((unixFile*)id)->fullSync = v; +*/ +static void os2SetFullSync( OsFile *id, int v ){ + return; +} + +/* +** Return the underlying file handle for an OsFile +*/ +static int os2FileHandle( OsFile *id ){ + return (int)((os2File*)id)->h; +} + +/* +** Return an integer that indices the type of lock currently held +** by this handle. (Used for testing and analysis only.) +*/ +static int os2LockState( OsFile *id ){ + return ((os2File*)id)->locktype; +} + +/* +** This vector defines all the methods that can operate on an OsFile +** for os2. +*/ +static const IoMethod sqlite3Os2IoMethod = { + os2Close, + os2OpenDirectory, + os2Read, + os2Write, + os2Seek, + os2Truncate, + os2Sync, + os2SetFullSync, + os2FileHandle, + os2FileSize, + os2Lock, + os2Unlock, + os2LockState, + os2CheckReservedLock, +}; + +/* +** Allocate memory for an OsFile. Initialize the new OsFile +** to the value given in pInit and return a pointer to the new +** OsFile. If we run out of memory, close the file and return NULL. +*/ +int allocateOs2File( os2File *pInit, OsFile **pld ){ + os2File *pNew; + pNew = sqliteMalloc( sizeof(*pNew) ); + if( pNew==0 ){ + DosClose( pInit->h ); + *pld = 0; + return SQLITE_NOMEM; + }else{ + *pNew = *pInit; + pNew->pMethod = &sqlite3Os2IoMethod; + pNew->locktype = NO_LOCK; + *pld = (OsFile*)pNew; + OpenCounter(+1); + return SQLITE_OK; + } +} + +#endif /* SQLITE_OMIT_DISKIO */ +/*************************************************************************** +** Everything above deals with file I/O. Everything that follows deals +** with other miscellanous aspects of the operating system interface +****************************************************************************/ + +/* +** Get information to seed the random number generator. The seed +** is written into the buffer zBuf[256]. The calling function must +** supply a sufficiently large buffer. +*/ +int sqlite3Os2RandomSeed( char *zBuf ){ + /* We have to initialize zBuf to prevent valgrind from reporting + ** errors. The reports issued by valgrind are incorrect - we would + ** prefer that the randomness be increased by making use of the + ** uninitialized space in zBuf - but valgrind errors tend to worry + ** some users. Rather than argue, it seems easier just to initialize + ** the whole array and silence valgrind, even if that means less randomness + ** in the random seed. + ** + ** When testing, initializing zBuf[] to zero is all we do. That means + ** that we always use the same random number sequence.* This makes the + ** tests repeatable. + */ + memset( zBuf, 0, 256 ); + DosGetDateTime( (PDATETIME)zBuf ); + return SQLITE_OK; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +int sqlite3Os2Sleep( int ms ){ + DosSleep( ms ); + return ms; +} + +/* +** Static variables used for thread synchronization +*/ +static int inMutex = 0; +#ifdef SQLITE_OS2_THREADS +static ULONG mutexOwner; +#endif + +/* +** The following pair of routines implement mutual exclusion for +** multi-threaded processes. Only a single thread is allowed to +** executed code that is surrounded by EnterMutex() and LeaveMutex(). +** +** SQLite uses only a single Mutex. There is not much critical +** code and what little there is executes quickly and without blocking. +*/ +void sqlite3Os2EnterMutex(){ + PTIB ptib; +#ifdef SQLITE_OS2_THREADS + DosEnterCritSec(); + DosGetInfoBlocks( &ptib, NULL ); + mutexOwner = ptib->tib_ptib2->tib2_ultid; +#endif + assert( !inMutex ); + inMutex = 1; +} +void sqlite3Os2LeaveMutex(){ + PTIB ptib; + assert( inMutex ); + inMutex = 0; +#ifdef SQLITE_OS2_THREADS + DosGetInfoBlocks( &ptib, NULL ); + assert( mutexOwner == ptib->tib_ptib2->tib2_ultid ); + DosExitCritSec(); +#endif +} + +/* +** Return TRUE if the mutex is currently held. +** +** If the thisThreadOnly parameter is true, return true if and only if the +** calling thread holds the mutex. If the parameter is false, return +** true if any thread holds the mutex. +*/ +int sqlite3Os2InMutex( int thisThreadOnly ){ +#ifdef SQLITE_OS2_THREADS + PTIB ptib; + DosGetInfoBlocks( &ptib, NULL ); + return inMutex>0 && (thisThreadOnly==0 || mutexOwner==ptib->tib_ptib2->tib2_ultid); +#else + return inMutex>0; +#endif +} + +/* +** The following variable, if set to a non-zero value, becomes the result +** returned from sqlite3OsCurrentTime(). This is used for testing. +*/ +#ifdef SQLITE_TEST +int sqlite3_current_time = 0; +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +int sqlite3Os2CurrentTime( double *prNow ){ + double now; + USHORT second, minute, hour, + day, month, year; + DATETIME dt; + DosGetDateTime( &dt ); + second = (USHORT)dt.seconds; + minute = (USHORT)dt.minutes + dt.timezone; + hour = (USHORT)dt.hours; + day = (USHORT)dt.day; + month = (USHORT)dt.month; + year = (USHORT)dt.year; + + /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html + http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */ + /* Calculate the Julian days */ + now = day - 32076 + + 1461*(year + 4800 + (month - 14)/12)/4 + + 367*(month - 2 - (month - 14)/12*12)/12 - + 3*((year + 4900 + (month - 14)/12)/100)/4; + + /* Add the fractional hours, mins and seconds */ + now += (hour + 12.0)/24.0; + now += minute/1440.0; + now += second/86400.0; + *prNow = now; +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *prNow = sqlite3_current_time/86400.0 + 2440587.5; + } +#endif + return 0; +} + +/* +** Remember the number of thread-specific-data blocks allocated. +** Use this to verify that we are not leaking thread-specific-data. +** Ticket #1601 +*/ +#ifdef SQLITE_TEST +int sqlite3_tsd_count = 0; +# define TSD_COUNTER_INCR InterlockedIncrement( &sqlite3_tsd_count ) +# define TSD_COUNTER_DECR InterlockedDecrement( &sqlite3_tsd_count ) +#else +# define TSD_COUNTER_INCR /* no-op */ +# define TSD_COUNTER_DECR /* no-op */ +#endif + +/* +** If called with allocateFlag>1, then return a pointer to thread +** specific data for the current thread. Allocate and zero the +** thread-specific data if it does not already exist necessary. +** +** If called with allocateFlag==0, then check the current thread +** specific data. Return it if it exists. If it does not exist, +** then return NULL. +** +** If called with allocateFlag<0, check to see if the thread specific +** data is allocated and is all zero. If it is then deallocate it. +** Return a pointer to the thread specific data or NULL if it is +** unallocated or gets deallocated. +*/ +ThreadData *sqlite3Os2ThreadSpecificData( int allocateFlag ){ + static ThreadData **s_ppTsd = NULL; + static const ThreadData zeroData = {0, 0, 0}; + ThreadData *pTsd; + + if( !s_ppTsd ){ + sqlite3OsEnterMutex(); + if( !s_ppTsd ){ + PULONG pul; + APIRET rc = DosAllocThreadLocalMemory(1, &pul); + if( rc != NO_ERROR ){ + sqlite3OsLeaveMutex(); + return 0; + } + s_ppTsd = (ThreadData **)pul; + } + sqlite3OsLeaveMutex(); + } + pTsd = *s_ppTsd; + if( allocateFlag>0 ){ + if( !pTsd ){ + pTsd = sqlite3OsMalloc( sizeof(zeroData) ); + if( pTsd ){ + *pTsd = zeroData; + *s_ppTsd = pTsd; + TSD_COUNTER_INCR; + } + } + }else if( pTsd!=0 && allocateFlag<0 + && memcmp( pTsd, &zeroData, sizeof(ThreadData) )==0 ){ + sqlite3OsFree(pTsd); + *s_ppTsd = NULL; + TSD_COUNTER_DECR; + pTsd = 0; + } + return pTsd; +} +#endif /* OS_OS2 */ ============================================================ --- sqlite/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3 +++ sqlite/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3 @@ -0,0 +1,73 @@ +/* +** 2004 May 22 +** +** 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 header file defined OS-specific features for OS/2. +*/ +#ifndef _SQLITE_OS_OS2_H_ +#define _SQLITE_OS_OS2_H_ + +/* +** standard include files. +*/ +#include +#include +#include +#include + +/* +** Macros used to determine whether or not to use threads. The +** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for +** Posix threads and SQLITE_W32_THREADS is defined if we are +** synchronizing using Win32 threads. +*/ +/* this mutex implementation only available with EMX */ +#if defined(THREADSAFE) && THREADSAFE +# include +# include +# define SQLITE_OS2_THREADS 1 +#endif + +/* +** The OsFile structure is a operating-system independing representation +** of an open file handle. It is defined differently for each architecture. +** +** This is the definition for Unix. +** +** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK, +** PENDING_LOCK or EXCLUSIVE_LOCK. +*/ +typedef struct OsFile OsFile; +struct OsFile { + int h; /* The file descriptor (LHANDLE) */ + int locked; /* True if this user holds the lock */ + int delOnClose; /* True if file is to be deleted on close */ + char *pathToDel; /* Name of file to delete on close */ + unsigned char locktype; /* The type of lock held on this fd */ + unsigned char isOpen; /* True if needs to be closed */ + unsigned char fullSync; +}; + +/* +** Maximum number of characters in a temporary file name +*/ +#define SQLITE_TEMPNAME_SIZE 200 + +/* +** Minimum interval supported by sqlite3OsSleep(). +*/ +#define SQLITE_MIN_SLEEP_MS 1 + +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0600 +#endif + +#endif /* _SQLITE_OS_OS2_H_ */ ============================================================ --- ChangeLog 7a0eb7f7c256403027c14a0e578ca26b19c036e2 +++ ChangeLog 73525808bf250d9d6cdedb1b0762c00940ac0680 @@ -1,3 +1,8 @@ +2006-06-07 Matthew Gregan + + * sqlite/*: Import SQLite 3.3.6. + * Makefile.am, configure.ac: Test for fdatasync and usleep. + 2006-06-07 Graydon Hoare * netxx_pipe.cc (simple_pipe_test): Attempt to fix broken unit ============================================================ --- Makefile.am 3c8a4501c0b6a6823dd877796008968e06d23199 +++ Makefile.am 0cd884200807c9d0794a74633c3283df45da028f @@ -289,7 +289,7 @@ SUFFIXES = .gch AM_CPPFLAGS = -AM_CFLAGS = $(AM_CPPFLAGS) -DTEMP_STORE=1 -DNDEBUG -DBOOST_DISABLE_THREADS -DBOOST_SP_DISABLE_THREADS -DSQLITE_OMIT_CURSOR $(SQLITE_CPPFLAGS) +AM_CFLAGS = $(AM_CPPFLAGS) -DTEMP_STORE=1 -DNDEBUG -DBOOST_DISABLE_THREADS -DBOOST_SP_DISABLE_THREADS -DSQLITE_OMIT_CURSOR -DTHREADSAFE=0 -DSQLITE_THREAD_OVERRIDE_LOCK=-1 $(SQLITE_CPPFLAGS) AM_CXXFLAGS = $(AM_CPPFLAGS) -DNDEBUG -DBOOST_DISABLE_THREADS -DBOOST_SP_DISABLE_THREADS AM_LDFLAGS = ============================================================ --- configure.ac 824721ae0b37ed846b0240a912e197eb69d4bd23 +++ configure.ac 3faced834db143b4501acf74123f70fef37148df @@ -334,7 +334,10 @@ AC_SEARCH_LIBS([inet_aton], [resolv]) AC_SEARCH_LIBS([accept], [socket]) AC_SEARCH_LIBS([inet_ntoa], [nsl]) -AC_SEARCH_LIBS([fdatasync], [rt]) +AC_SEARCH_LIBS([fdatasync], [rt], AC_DEFINE(HAVE_FDATASYNC)) +AH_TEMPLATE([HAVE_FDATASYNC], [For SQLite; use fdatasync if available]) +AC_SEARCH_LIBS([usleep], [rt], AC_DEFINE(HAVE_USLEEP)) +AH_TEMPLATE([HAVE_USLEEP], [For SQLite; use usleep if available]) AC_CHECK_LIB([z], [deflate], , AC_MSG_FAILURE([zlib is required])) # Now let the user specify whether he wants large file support or not in ============================================================ --- sqlite/attach.c 514f90623c891143846625afcab409d6b4986565 +++ sqlite/attach.c 27a31d3b89d7ebb5b358847607b1ec795384123c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.50 2006/04/05 11:57:37 drh Exp $ +** $Id: attach.c,v 1.52 2006/05/25 11:52:38 drh Exp $ */ #include "sqliteInt.h" @@ -73,6 +73,8 @@ zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); + if( zFile==0 ) zFile = ""; + if( zName==0 ) zName = ""; /* Check for the following errors: ** @@ -82,7 +84,7 @@ */ if( db->nDb>=MAX_ATTACHED+2 ){ sqlite3_snprintf( - 127, zErr, "too many attached databases - max %d", MAX_ATTACHED + sizeof(zErr), zErr, "too many attached databases - max %d", MAX_ATTACHED ); goto attach_error; } @@ -92,8 +94,8 @@ } for(i=0; inDb; i++){ char *z = db->aDb[i].zName; - if( z && sqlite3StrICmp(z, zName)==0 ){ - sqlite3_snprintf(127, zErr, "database %s is already in use", zName); + if( z && zName && sqlite3StrICmp(z, zName)==0 ){ + sqlite3_snprintf(sizeof(zErr), zErr, "database %s is already in use", zName); goto attach_error; } } @@ -186,10 +188,10 @@ sqlite3ResetInternalSchema(db, 0); db->nDb = iDb; if( rc==SQLITE_NOMEM ){ - sqlite3MallocFailed(); - sqlite3_snprintf(127, zErr, "out of memory"); + if( !sqlite3MallocFailed() ) sqlite3FailedMalloc(); + sqlite3_snprintf(sizeof(zErr),zErr, "out of memory"); }else{ - sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile); + sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile); } goto attach_error; } @@ -226,7 +228,7 @@ Db *pDb = 0; char zErr[128]; - assert(zName); + if( zName==0 ) zName = ""; for(i=0; inDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; @@ -234,11 +236,11 @@ } if( i>=db->nDb ){ - sqlite3_snprintf(sizeof(zErr), zErr, "no such database: %s", zName); + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); goto detach_error; } if( i<2 ){ - sqlite3_snprintf(sizeof(zErr), zErr, "cannot detach database %s", zName); + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } if( !db->autoCommit ){ ============================================================ --- sqlite/build.c be0629119df8c1e09050a8fcbf182112f00e3b14 +++ sqlite/build.c eefefdc88cb342bc0f7cb41ccdf3930739ab50e9 @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.393 2006/03/24 03:36:26 drh Exp $ +** $Id: build.c,v 1.394 2006/05/11 23:14:59 drh Exp $ */ #include "sqliteInt.h" #include @@ -2638,9 +2638,13 @@ int i; assert( a!=0 ); a[0] = 1000000; - for(i=pIdx->nColumn; i>=1; i--){ - a[i] = 10; + for(i=pIdx->nColumn; i>=5; i--){ + a[i] = 5; } + while( i>=1 ){ + a[i] = 11 - i; + i--; + } if( pIdx->onError!=OE_None ){ a[pIdx->nColumn] = 1; } ============================================================ --- sqlite/callback.c d8c5ab1cd6f3b7182b2ee63bf53f1b69c0f74306 +++ sqlite/callback.c fd9bb39f7ff6b52bad8365617abc61c720640429 @@ -13,7 +13,7 @@ ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** -** $Id: callback.c,v 1.14 2006/03/14 11:08:28 drh Exp $ +** $Id: callback.c,v 1.15 2006/05/24 12:43:27 drh Exp $ */ #include "sqliteInt.h" @@ -362,6 +362,7 @@ sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1); + p->enc = SQLITE_UTF8; } return p; } ============================================================ --- sqlite/expr.c c85d7bee7d8e3184e00166c2c2ab6edd57b60486 +++ sqlite/expr.c f1ad18d0b7bb3abbf09cb30871ae6e7618447bc5 @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.257 2006/03/17 13:56:34 drh Exp $ +** $Id: expr.c,v 1.258 2006/05/23 23:22:29 drh Exp $ */ #include "sqliteInt.h" #include @@ -1367,7 +1367,7 @@ struct ExprList_item *pItem; if( !affinity ){ - affinity = SQLITE_AFF_NUMERIC; + affinity = SQLITE_AFF_NONE; } keyInfo.aColl[0] = pExpr->pLeft->pColl; ============================================================ --- sqlite/func.c 380f2f8e555ccbf899e65f01475c4ac13c478dc2 +++ sqlite/func.c acbbf533b55221f26760798d99b37de3ac5678fe @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.126 2006/03/16 16:19:56 drh Exp $ +** $Id: func.c,v 1.128 2006/05/11 13:25:39 drh Exp $ */ #include "sqliteInt.h" #include @@ -204,7 +204,8 @@ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); - sqlite3_result_double(context, atof(zBuf)); + sqlite3AtoF(zBuf, &r); + sqlite3_result_double(context, r); } /* @@ -839,16 +840,8 @@ ** that it returns NULL if it sums over no inputs. TOTAL returns ** 0.0 in that case. In addition, TOTAL always returns a float where ** SUM might return an integer if it never encounters a floating point -** value. -** -** I am told that SUM() should raise an exception if it encounters -** a integer overflow. But after pondering this, I decided that -** behavior leads to brittle programs. So instead, I have coded -** SUM() to revert to using floating point if it encounters an -** integer overflow. The answer may not be exact, but it will be -** close. If the SUM() function returns an integer, the value is -** exact. If SUM() returns a floating point value, it means the -** value might be approximated. +** value. TOTAL never fails, but SUM might through an exception if +** it overflows an integer. */ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ SumCtx *p; ============================================================ --- sqlite/main.c 5cdd81aaf159836b5ca277192da4f7461fd15078 +++ sqlite/main.c 928d93cfd5d72be3a619ee908182c9432151a99e @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.339 2006/03/16 16:19:56 drh Exp $ +** $Id: main.c,v 1.340 2006/05/24 12:43:27 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -851,9 +851,6 @@ } db->aDb[0].pSchema = sqlite3SchemaGet(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(0); - if( db->aDb[0].pSchema ){ - ENC(db) = SQLITE_UTF8; - } /* The default safety_level for the main database is 'full'; for the temp ============================================================ --- sqlite/os.h 93035a0e3b9dd05cdd0aaef32ea28ca28e02fe78 +++ sqlite/os.h 46fad85c707ad8643622bab9d894a642940850aa @@ -27,12 +27,19 @@ # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) # define OS_WIN 1 # define OS_UNIX 0 +# define OS_OS2 0 +# elif defined(_EMX_) || defined(_OS2) || defined(OS2) || defined(OS_OS2) +# define OS_WIN 0 +# define OS_UNIX 0 +# define OS_OS2 1 # else # define OS_WIN 0 # define OS_UNIX 1 +# define OS_OS2 0 # endif # else # define OS_UNIX 0 +# define OS_OS2 0 # endif #else # ifndef OS_WIN @@ -47,6 +54,14 @@ #if OS_WIN # include # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) +#elif OS_OS2 +# define INCL_DOSDATETIME +# define INCL_DOSFILEMGR +# define INCL_DOSERRORS +# define INCL_DOSMISC +# define INCL_DOSPROCESS +# include +# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) #else # define SQLITE_TEMPNAME_SIZE 200 #endif @@ -72,7 +87,7 @@ #endif /* -** Define the interfaces for Unix and for Windows. +** Define the interfaces for Unix, Windows, and OS/2. */ #if OS_UNIX #define sqlite3OsOpenReadWrite sqlite3UnixOpenReadWrite @@ -118,7 +133,30 @@ #define sqlite3OsFree sqlite3GenericFree #define sqlite3OsAllocationSize sqlite3GenericAllocationSize #endif +#if OS_OS2 +#define sqlite3OsOpenReadWrite sqlite3Os2OpenReadWrite +#define sqlite3OsOpenExclusive sqlite3Os2OpenExclusive +#define sqlite3OsOpenReadOnly sqlite3Os2OpenReadOnly +#define sqlite3OsDelete sqlite3Os2Delete +#define sqlite3OsFileExists sqlite3Os2FileExists +#define sqlite3OsFullPathname sqlite3Os2FullPathname +#define sqlite3OsIsDirWritable sqlite3Os2IsDirWritable +#define sqlite3OsSyncDirectory sqlite3Os2SyncDirectory +#define sqlite3OsTempFileName sqlite3Os2TempFileName +#define sqlite3OsRandomSeed sqlite3Os2RandomSeed +#define sqlite3OsSleep sqlite3Os2Sleep +#define sqlite3OsCurrentTime sqlite3Os2CurrentTime +#define sqlite3OsEnterMutex sqlite3Os2EnterMutex +#define sqlite3OsLeaveMutex sqlite3Os2LeaveMutex +#define sqlite3OsInMutex sqlite3Os2InMutex +#define sqlite3OsThreadSpecificData sqlite3Os2ThreadSpecificData +#define sqlite3OsMalloc sqlite3GenericMalloc +#define sqlite3OsRealloc sqlite3GenericRealloc +#define sqlite3OsFree sqlite3GenericFree +#define sqlite3OsAllocationSize sqlite3GenericAllocationSize +#endif + /* ** If using an alternative OS interface, then we must have an "os_other.h" ** header file available for that interface. Presumably the "os_other.h" ============================================================ --- sqlite/os_unix.c 35ad4d81c90800f509d28580742b67906d289223 +++ sqlite/os_unix.c 17d91581a0ab478a06cb6f257b707a4c4a93e5a7 @@ -752,9 +752,6 @@ CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag); assert( 0==*pId ); - if( access(zFilename, 0)==0 ){ - return SQLITE_CANTOPEN; - } f.h = open(zFilename, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, SQLITE_DEFAULT_FILE_PERMISSIONS); ============================================================ --- sqlite/os_win.c 8ced9ac82670bbf77492961a2f7ff80a87f1404f +++ sqlite/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f @@ -476,22 +476,38 @@ #endif /* OS_WINCE */ /* -** Delete the named file +** Delete the named file. +** +** Note that windows does not allow a file to be deleted if some other +** process has it open. Sometimes a virus scanner or indexing program +** will open a journal file shortly after it is created in order to do +** whatever it is it does. While this other process is holding the +** file open, we will be unable to delete it. To work around this +** problem, we delay 100 milliseconds and try to delete again. Up +** to MX_DELETION_ATTEMPTs deletion attempts are run before giving +** up and returning an error. */ +#define MX_DELETION_ATTEMPTS 3 int sqlite3WinDelete(const char *zFilename){ WCHAR *zWide = utf8ToUnicode(zFilename); + int cnt = 0; + int rc; if( zWide ){ - DeleteFileW(zWide); + do{ + rc = DeleteFileW(zWide); + }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); sqliteFree(zWide); }else{ #if OS_WINCE return SQLITE_NOMEM; #else - DeleteFileA(zFilename); + do{ + rc = DeleteFileA(zFilename); + }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); #endif } TRACE2("DELETE \"%s\"\n", zFilename); - return SQLITE_OK; + return rc==0 ? SQLITE_OK : SQLITE_IOERR; } /* @@ -550,7 +566,7 @@ if( h==INVALID_HANDLE_VALUE ){ h = CreateFileW(zWide, GENERIC_READ, - FILE_SHARE_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, @@ -587,7 +603,7 @@ if( h==INVALID_HANDLE_VALUE ){ h = CreateFileA(zFilename, GENERIC_READ, - FILE_SHARE_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, @@ -624,6 +640,12 @@ ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. +** +** Sometimes if we have just deleted a prior journal file, windows +** will fail to open a new one because there is a "pending delete". +** To work around this bug, we pause for 100 milliseconds and attempt +** a second open after the first one fails. The whole operation only +** fails if both open attempts are unsuccessful. */ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ winFile f; @@ -638,27 +660,33 @@ } #endif if( zWide ){ - h = CreateFileW(zWide, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - fileflags, - NULL - ); + int cnt = 0; + do{ + h = CreateFileW(zWide, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + fileflags, + NULL + ); + }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) ); sqliteFree(zWide); }else{ #if OS_WINCE return SQLITE_NOMEM; #else - h = CreateFileA(zFilename, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - fileflags, - NULL - ); + int cnt = 0; + do{ + h = CreateFileA(zFilename, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + fileflags, + NULL + ); + }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) ); #endif /* OS_WINCE */ } if( h==INVALID_HANDLE_VALUE ){ @@ -796,12 +824,24 @@ /* ** Close a file. +** +** It is reported that an attempt to close a handle might sometimes +** fail. This is a very unreasonable result, but windows is notorious +** for being unreasonable so I do not doubt that it might happen. If +** the close fails, we pause for 100 milliseconds and try again. As +** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before +** giving up and returning an error. */ +#define MX_CLOSE_ATTEMPT 3 static int winClose(OsFile **pId){ winFile *pFile; + int rc = 1; if( pId && (pFile = (winFile*)*pId)!=0 ){ + int rc, cnt = 0; TRACE2("CLOSE %d\n", pFile->h); - CloseHandle(pFile->h); + do{ + rc = CloseHandle(pFile->h); + }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if OS_WINCE winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ @@ -813,7 +853,7 @@ sqliteFree(pFile); *pId = 0; } - return SQLITE_OK; + return rc ? SQLITE_OK : SQLITE_IOERR; } /* ============================================================ --- sqlite/pager.c 33186636a07eeaf34028083c32b27b9647556be7 +++ sqlite/pager.c ddd05666bb89808a516baef2c186d6a75887ae90 @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.265 2006/03/26 20:49:18 drh Exp $ +** @(#) $Id: pager.c,v 1.268 2006/05/07 17:49:39 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -161,7 +161,8 @@ u8 needSync; /* Sync journal before writing this page */ u8 alwaysRollback; /* Disable dont_rollback() for this page */ short int nRef; /* Number of users of this page */ - PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ + PgHdr *pDirty, *pPrevDirty; /* Dirty pages sorted by PgHdr.pgno */ + u32 notUsed; /* Buffer space */ #ifdef SQLITE_CHECK_PAGES u32 pageHash; #endif @@ -208,24 +209,6 @@ ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra]) /* -** How big to make the hash table used for locating in-memory pages -** by page number. This macro looks a little silly, but is evaluated -** at compile-time, not run-time (at least for gcc this is true). -*/ -#define N_PG_HASH (\ - (MAX_PAGES>1024)?2048: \ - (MAX_PAGES>512)?1024: \ - (MAX_PAGES>256)?512: \ - (MAX_PAGES>128)?256: \ - (MAX_PAGES>64)?128:64 \ -) - -/* -** Hash a page number -*/ -#define pager_hash(PN) ((PN)&(N_PG_HASH-1)) - -/* ** A open page cache is an instance of the following structure. ** ** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, SQLITE_PROTOCOL @@ -280,6 +263,7 @@ PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */ PgHdr *pAll; /* List of all pages */ PgHdr *pStmt; /* List of pages in the statement subjournal */ + PgHdr *pDirty; /* List of all dirty pages */ i64 journalOff; /* Current byte offset in the journal file */ i64 journalHdr; /* Byte offset to previous journal header */ i64 stmtHdrOff; /* First journal header written this statement */ @@ -294,7 +278,8 @@ void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void *pCodecArg; /* First argument to xCodec() */ - PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */ + int nHash; /* Size of the pager hash table */ + PgHdr **aHash; /* Hash table to map page number to PgHdr */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Pager *pNext; /* Linked list of pagers in this thread */ #endif @@ -401,7 +386,34 @@ # define REFINFO(X) #endif + /* +** Change the size of the pager hash table to N. N must be a power +** of two. +*/ +static void pager_resize_hash_table(Pager *pPager, int N){ + PgHdr **aHash, *pPg; + assert( N>0 && (N&(N-1))==0 ); + aHash = sqliteMalloc( sizeof(aHash[0])*N ); + if( aHash==0 ){ + /* Failure to rehash is not an error. It is only a performance hit. */ + return; + } + sqliteFree(pPager->aHash); + pPager->nHash = N; + pPager->aHash = aHash; + for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ + int h = pPg->pgno & (N-1); + pPg->pNextHash = aHash[h]; + if( aHash[h] ){ + aHash[h]->pPrevHash = pPg; + } + aHash[h] = pPg; + pPg->pPrevHash = 0; + } +} + +/* ** Read a 32-bit integer from the given file descriptor. Store the integer ** that is read in *pRes. Return SQLITE_OK if everything worked, or an ** error code is something goes wrong. @@ -820,7 +832,9 @@ ** a pointer to the page or NULL if not found. */ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ - PgHdr *p = pPager->aHash[pager_hash(pgno)]; + PgHdr *p; + if( pPager->aHash==0 ) return 0; + p = pPager->aHash[pgno & (pPager->nHash-1)]; while( p && p->pgno!=pgno ){ p = p->pNextHash; } @@ -844,8 +858,10 @@ pPager->pFirstSynced = 0; pPager->pLast = 0; pPager->pAll = 0; - memset(pPager->aHash, 0, sizeof(pPager->aHash)); + pPager->nHash = 0; + sqliteFree(pPager->aHash); pPager->nPage = 0; + pPager->aHash = 0; if( pPager->state>=PAGER_RESERVED ){ sqlite3pager_rollback(pPager); } @@ -892,6 +908,7 @@ pPg->pageHash = pager_pagehash(pPg); #endif } + pPager->pDirty = 0; pPager->dirtyCache = 0; pPager->nRec = 0; }else{ @@ -937,6 +954,9 @@ return cksum; } +/* Forward declaration */ +static void makeClean(PgHdr*); + /* ** Read a single page from the journal file opened on file descriptor ** jfd. Playback this one page. @@ -1014,7 +1034,9 @@ if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize); } - if( pPg ) pPg->dirty = 0; + if( pPg ){ + makeClean(pPg); + } } if( pPg ){ /* No page should ever be explicitly rolled back that is in use, except @@ -1164,6 +1186,7 @@ pPg->pageHash = pager_pagehash(pPg); #endif } + pPager->pDirty = 0; return rc; } @@ -1805,13 +1828,26 @@ return n; } + +#ifndef SQLITE_OMIT_MEMORYDB /* +** Clear a PgHistory block +*/ +static void clearHistory(PgHistory *pHist){ + sqliteFree(pHist->pOrig); + sqliteFree(pHist->pStmt); + pHist->pOrig = 0; + pHist->pStmt = 0; +} +#else +#define clearHistory(x) +#endif + +/* ** Forward declaration */ static int syncJournal(Pager*); -static void clearHistory(PgHistory*); - /* ** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate ** that the page is not part of any hash chain. This is required because the @@ -1827,10 +1863,10 @@ pPg->pNextHash->pPrevHash = pPg->pPrevHash; } if( pPg->pPrevHash ){ - assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg ); + assert( pPager->aHash[pPg->pgno & (pPager->nHash-1)]!=pPg ); pPg->pPrevHash->pNextHash = pPg->pNextHash; }else{ - int h = pager_hash(pPg->pgno); + int h = pPg->pgno & (pPager->nHash-1); assert( pPager->aHash[h]==pPg ); pPager->aHash[h] = pPg->pNextHash; } @@ -1895,6 +1931,7 @@ }else{ *ppPg = pPg->pNextAll; unlinkPage(pPg); + makeClean(pPg); sqliteFree(pPg); pPager->nPage--; } @@ -2061,7 +2098,7 @@ pTmp->pNext = pPager->pNext; } #endif - + sqliteFree(pPager->aHash); sqliteFree(pPager); return SQLITE_OK; } @@ -2292,15 +2329,7 @@ ** collected even if they are still in use. */ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ - PgHdr *p, *pList; - pList = 0; - for(p=pPager->pAll; p; p=p->pNextAll){ - if( p->dirty ){ - p->pDirty = pList; - pList = p; - } - } - return pList; + return pPager->pDirty; } /* @@ -2375,6 +2404,8 @@ if( pPg->dirty ){ int rc; assert( pPg->needSync==0 ); + makeClean(pPg); + pPg->dirty = 1; pPg->pDirty = 0; rc = pager_write_pagelist( pPg ); if( rc!=SQLITE_OK ){ @@ -2605,6 +2636,13 @@ TEST_INCR(pPager->nMiss); if( pPager->nPagemxPage || pPager->pFirst==0 || MEMDB ){ /* Create a new page */ + if( pPager->nPage>=pPager->nHash ){ + pager_resize_hash_table(pPager, + pPager->nHash<256 ? 256 : pPager->nHash*2); + if( pPager->nHash==0 ){ + return SQLITE_NOMEM; + } + } pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory) ); @@ -2646,7 +2684,7 @@ }else{ page_remove_from_stmt_list(pPg); } - pPg->dirty = 0; + makeClean(pPg); pPg->nRef = 1; REFINFO(pPg); @@ -2693,7 +2731,7 @@ } /* Link the page into the page hash table */ - h = pager_hash(pgno); + h = pgno & (pPager->nHash-1); pPg->pNextHash = pPager->aHash[h]; pPager->aHash[h] = pPg; if( pPg->pNextHash ){ @@ -2923,6 +2961,42 @@ } /* +** Make a page dirty. Set its dirty flag and add it to the dirty +** page list. +*/ +static void makeDirty(PgHdr *pPg){ + if( pPg->dirty==0 ){ + Pager *pPager = pPg->pPager; + pPg->dirty = 1; + pPg->pDirty = pPager->pDirty; + if( pPager->pDirty ){ + pPager->pDirty->pPrevDirty = pPg; + } + pPg->pPrevDirty = 0; + pPager->pDirty = pPg; + } +} + +/* +** Make a page clean. Clear its dirty bit and remove it from the +** dirty page list. +*/ +static void makeClean(PgHdr *pPg){ + if( pPg->dirty ){ + pPg->dirty = 0; + if( pPg->pDirty ){ + pPg->pDirty->pPrevDirty = pPg->pPrevDirty; + } + if( pPg->pPrevDirty ){ + pPg->pPrevDirty->pDirty = pPg->pDirty; + }else{ + pPg->pPager->pDirty = pPg->pDirty; + } + } +} + + +/* ** Mark a data page as writeable. The page is written into the journal ** if it is not there already. This routine must be called before making ** changes to a page. @@ -2960,7 +3034,7 @@ /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ - pPg->dirty = 1; + makeDirty(pPg); if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){ pPager->dirtyCache = 1; }else{ @@ -3167,7 +3241,7 @@ */ }else{ TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager)); - pPg->dirty = 0; + makeClean(pPg); #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif @@ -3206,21 +3280,7 @@ } -#ifndef SQLITE_OMIT_MEMORYDB /* -** Clear a PgHistory block -*/ -static void clearHistory(PgHistory *pHist){ - sqliteFree(pHist->pOrig); - sqliteFree(pHist->pStmt); - pHist->pOrig = 0; - pHist->pStmt = 0; -} -#else -#define clearHistory(x) -#endif - -/* ** Commit all changes to the database and release the write lock. ** ** If the commit fails for any reason, a rollback attempt is made @@ -3249,6 +3309,7 @@ pPg->pPrevStmt = pPg->pNextStmt = 0; pPg = pPg->pDirty; } + pPager->pDirty = 0; #ifndef NDEBUG for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); @@ -3316,12 +3377,11 @@ p->inJournal = 0; p->inStmt = 0; p->pPrevStmt = p->pNextStmt = 0; - if( pPager->xReiniter ){ pPager->xReiniter(PGHDR_TO_DATA(p), pPager->pageSize); } - } + pPager->pDirty = 0; pPager->pStmt = 0; pPager->dbSize = pPager->origDbSize; memoryTruncate(pPager); @@ -3716,7 +3776,7 @@ if( pPgOld ){ assert( pPgOld->nRef==0 ); unlinkHashChain(pPager, pPgOld); - pPgOld->dirty = 0; + makeClean(pPgOld); if( pPgOld->needSync ){ assert( pPgOld->inJournal ); pPg->inJournal = 1; @@ -3727,7 +3787,7 @@ /* Change the page number for pPg and insert it into the new hash-chain. */ pPg->pgno = pgno; - h = pager_hash(pgno); + h = pgno & (pPager->nHash-1); if( pPager->aHash[h] ){ assert( pPager->aHash[h]->pPrevHash==0 ); pPager->aHash[h]->pPrevHash = pPg; @@ -3736,7 +3796,7 @@ pPager->aHash[h] = pPg; pPg->pPrevHash = 0; - pPg->dirty = 1; + makeDirty(pPg); pPager->dirtyCache = 1; if( needSyncPgno ){ @@ -3757,7 +3817,7 @@ pPager->needSync = 1; DATA_TO_PGHDR(pNeedSync)->needSync = 1; DATA_TO_PGHDR(pNeedSync)->inJournal = 1; - DATA_TO_PGHDR(pNeedSync)->dirty = 1; + makeDirty(DATA_TO_PGHDR(pNeedSync)); sqlite3pager_unref(pNeedSync); } ============================================================ --- sqlite/parse.c 99da8c67793c0a37e0f1e5349be63339ca7061a6 +++ sqlite/parse.c 7edb838b64d4361c1b52c1b6b0e7ab0ce64e0695 @@ -7,7 +7,7 @@ #include "sqliteInt.h" #include "parse.h" -#line 57 "parse.y" +#line 56 "parse.y" /* ** An instance of this structure holds information about the @@ -1208,7 +1208,7 @@ case 154: case 188: case 205: -#line 371 "parse.y" +#line 373 "parse.y" {sqlite3SelectDelete((yypminor->yy239));} #line 1215 "parse.c" break; @@ -1223,7 +1223,7 @@ case 222: case 223: case 233: -#line 628 "parse.y" +#line 630 "parse.y" {sqlite3ExprDelete((yypminor->yy178));} #line 1230 "parse.c" break; @@ -1238,7 +1238,7 @@ case 212: case 215: case 221: -#line 859 "parse.y" +#line 861 "parse.y" {sqlite3ExprListDelete((yypminor->yy462));} #line 1245 "parse.c" break; @@ -1246,12 +1246,12 @@ case 192: case 200: case 201: -#line 499 "parse.y" +#line 501 "parse.y" {sqlite3SrcListDelete((yypminor->yy285));} #line 1253 "parse.c" break; case 197: -#line 560 "parse.y" +#line 562 "parse.y" { sqlite3ExprDelete((yypminor->yy270).pLimit); sqlite3ExprDelete((yypminor->yy270).pOffset); @@ -1261,23 +1261,23 @@ case 204: case 207: case 214: -#line 516 "parse.y" +#line 518 "parse.y" {sqlite3IdListDelete((yypminor->yy160));} #line 1268 "parse.c" break; case 229: case 234: -#line 953 "parse.y" +#line 955 "parse.y" {sqlite3DeleteTriggerStep((yypminor->yy247));} #line 1274 "parse.c" break; case 231: -#line 937 "parse.y" +#line 939 "parse.y" {sqlite3IdListDelete((yypminor->yy132).b);} #line 1279 "parse.c" break; case 236: -#line 1021 "parse.y" +#line 1023 "parse.y" {sqlite3ExprDelete((yypminor->yy292));} #line 1284 "parse.c" break; @@ -1427,10 +1427,11 @@ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ -#line 43 "parse.y" +#line 44 "parse.y" sqlite3ErrorMsg(pParse, "parser stack overflow"); -#line 1436 "parse.c" + pParse->parseError = 1; +#line 1437 "parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ return; } @@ -1801,61 +1802,61 @@ ** break; */ case 3: -#line 98 "parse.y" +#line 100 "parse.y" { sqlite3FinishCoding(pParse); } -#line 1809 "parse.c" +#line 1810 "parse.c" break; case 6: -#line 101 "parse.y" +#line 103 "parse.y" { sqlite3BeginParse(pParse, 0); } -#line 1814 "parse.c" +#line 1815 "parse.c" break; case 7: -#line 103 "parse.y" +#line 105 "parse.y" { sqlite3BeginParse(pParse, 1); } -#line 1819 "parse.c" +#line 1820 "parse.c" break; case 8: -#line 104 "parse.y" +#line 106 "parse.y" { sqlite3BeginParse(pParse, 2); } -#line 1824 "parse.c" +#line 1825 "parse.c" break; case 9: -#line 110 "parse.y" +#line 112 "parse.y" {sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy230);} -#line 1829 "parse.c" +#line 1830 "parse.c" break; case 13: -#line 115 "parse.y" +#line 117 "parse.y" {yygotominor.yy230 = TK_DEFERRED;} -#line 1834 "parse.c" +#line 1835 "parse.c" break; case 14: case 15: case 16: case 107: case 109: -#line 116 "parse.y" +#line 118 "parse.y" {yygotominor.yy230 = yymsp[0].major;} -#line 1843 "parse.c" +#line 1844 "parse.c" break; case 17: case 18: -#line 119 "parse.y" +#line 121 "parse.y" {sqlite3CommitTransaction(pParse);} -#line 1849 "parse.c" +#line 1850 "parse.c" break; case 19: -#line 121 "parse.y" +#line 123 "parse.y" {sqlite3RollbackTransaction(pParse);} -#line 1854 "parse.c" +#line 1855 "parse.c" break; case 21: -#line 126 "parse.y" +#line 128 "parse.y" { sqlite3StartTable(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,yymsp[-4].minor.yy230,0,yymsp[-2].minor.yy230); } -#line 1861 "parse.c" +#line 1862 "parse.c" break; case 22: case 25: @@ -1868,9 +1869,9 @@ case 113: case 210: case 213: -#line 130 "parse.y" +#line 132 "parse.y" {yygotominor.yy230 = 0;} -#line 1876 "parse.c" +#line 1877 "parse.c" break; case 23: case 24: @@ -1880,40 +1881,40 @@ case 111: case 211: case 214: -#line 131 "parse.y" +#line 133 "parse.y" {yygotominor.yy230 = 1;} -#line 1888 "parse.c" +#line 1889 "parse.c" break; case 26: -#line 137 "parse.y" +#line 139 "parse.y" { sqlite3EndTable(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy0,0); } -#line 1895 "parse.c" +#line 1896 "parse.c" break; case 27: -#line 140 "parse.y" +#line 142 "parse.y" { sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy239); sqlite3SelectDelete(yymsp[0].minor.yy239); } -#line 1903 "parse.c" +#line 1904 "parse.c" break; case 30: -#line 152 "parse.y" +#line 154 "parse.y" { yygotominor.yy384.z = yymsp[-2].minor.yy384.z; yygotominor.yy384.n = (pParse->sLastToken.z-yymsp[-2].minor.yy384.z) + pParse->sLastToken.n; } -#line 1911 "parse.c" +#line 1912 "parse.c" break; case 31: -#line 156 "parse.y" +#line 158 "parse.y" { sqlite3AddColumn(pParse,&yymsp[0].minor.yy384); yygotominor.yy384 = yymsp[0].minor.yy384; } -#line 1919 "parse.c" +#line 1920 "parse.c" break; case 32: case 33: @@ -1921,14 +1922,14 @@ case 35: case 36: case 250: -#line 166 "parse.y" +#line 168 "parse.y" {yygotominor.yy384 = yymsp[0].minor.yy0;} -#line 1929 "parse.c" +#line 1930 "parse.c" break; case 38: -#line 225 "parse.y" +#line 227 "parse.y" {sqlite3AddColumnType(pParse,&yymsp[0].minor.yy384);} -#line 1934 "parse.c" +#line 1935 "parse.c" break; case 39: case 42: @@ -1939,152 +1940,152 @@ case 238: case 248: case 249: -#line 226 "parse.y" +#line 228 "parse.y" {yygotominor.yy384 = yymsp[0].minor.yy384;} -#line 1947 "parse.c" +#line 1948 "parse.c" break; case 40: -#line 227 "parse.y" +#line 229 "parse.y" { yygotominor.yy384.z = yymsp[-3].minor.yy384.z; yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy384.z; } -#line 1955 "parse.c" +#line 1956 "parse.c" break; case 41: -#line 231 "parse.y" +#line 233 "parse.y" { yygotominor.yy384.z = yymsp[-5].minor.yy384.z; yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy384.z; } -#line 1963 "parse.c" +#line 1964 "parse.c" break; case 43: -#line 237 "parse.y" +#line 239 "parse.y" {yygotominor.yy384.z=yymsp[-1].minor.yy384.z; yygotominor.yy384.n=yymsp[0].minor.yy384.n+(yymsp[0].minor.yy384.z-yymsp[-1].minor.yy384.z);} -#line 1968 "parse.c" +#line 1969 "parse.c" break; case 44: -#line 239 "parse.y" +#line 241 "parse.y" { yygotominor.yy230 = atoi((char*)yymsp[0].minor.yy384.z); } -#line 1973 "parse.c" +#line 1974 "parse.c" break; case 45: -#line 240 "parse.y" +#line 242 "parse.y" { yygotominor.yy230 = -atoi((char*)yymsp[0].minor.yy384.z); } -#line 1978 "parse.c" +#line 1979 "parse.c" break; case 50: case 52: -#line 249 "parse.y" +#line 251 "parse.y" {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy178);} -#line 1984 "parse.c" +#line 1985 "parse.c" break; case 51: -#line 250 "parse.y" +#line 252 "parse.y" {sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy178);} -#line 1989 "parse.c" +#line 1990 "parse.c" break; case 53: -#line 252 "parse.y" +#line 254 "parse.y" { Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0); sqlite3AddDefaultValue(pParse,p); } -#line 1997 "parse.c" +#line 1998 "parse.c" break; case 54: -#line 256 "parse.y" +#line 258 "parse.y" { Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy384); sqlite3AddDefaultValue(pParse,p); } -#line 2005 "parse.c" +#line 2006 "parse.c" break; case 56: -#line 265 "parse.y" +#line 267 "parse.y" {sqlite3AddNotNull(pParse, yymsp[0].minor.yy230);} -#line 2010 "parse.c" +#line 2011 "parse.c" break; case 57: -#line 267 "parse.y" +#line 269 "parse.y" {sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy230,yymsp[0].minor.yy230,yymsp[-2].minor.yy230);} -#line 2015 "parse.c" +#line 2016 "parse.c" break; case 58: -#line 268 "parse.y" +#line 270 "parse.y" {sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy230,0,0,0,0);} -#line 2020 "parse.c" +#line 2021 "parse.c" break; case 59: -#line 269 "parse.y" +#line 271 "parse.y" {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy178);} -#line 2025 "parse.c" +#line 2026 "parse.c" break; case 60: -#line 271 "parse.y" +#line 273 "parse.y" {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy384,yymsp[-1].minor.yy462,yymsp[0].minor.yy230);} -#line 2030 "parse.c" +#line 2031 "parse.c" break; case 61: -#line 272 "parse.y" +#line 274 "parse.y" {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy230);} -#line 2035 "parse.c" +#line 2036 "parse.c" break; case 62: -#line 273 "parse.y" +#line 275 "parse.y" {sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy384.z, yymsp[0].minor.yy384.n);} -#line 2040 "parse.c" +#line 2041 "parse.c" break; case 65: -#line 286 "parse.y" +#line 288 "parse.y" { yygotominor.yy230 = OE_Restrict * 0x010101; } -#line 2045 "parse.c" +#line 2046 "parse.c" break; case 66: -#line 287 "parse.y" +#line 289 "parse.y" { yygotominor.yy230 = (yymsp[-1].minor.yy230 & yymsp[0].minor.yy13.mask) | yymsp[0].minor.yy13.value; } -#line 2050 "parse.c" +#line 2051 "parse.c" break; case 67: -#line 289 "parse.y" +#line 291 "parse.y" { yygotominor.yy13.value = 0; yygotominor.yy13.mask = 0x000000; } -#line 2055 "parse.c" +#line 2056 "parse.c" break; case 68: -#line 290 "parse.y" +#line 292 "parse.y" { yygotominor.yy13.value = yymsp[0].minor.yy230; yygotominor.yy13.mask = 0x0000ff; } -#line 2060 "parse.c" +#line 2061 "parse.c" break; case 69: -#line 291 "parse.y" +#line 293 "parse.y" { yygotominor.yy13.value = yymsp[0].minor.yy230<<8; yygotominor.yy13.mask = 0x00ff00; } -#line 2065 "parse.c" +#line 2066 "parse.c" break; case 70: -#line 292 "parse.y" +#line 294 "parse.y" { yygotominor.yy13.value = yymsp[0].minor.yy230<<16; yygotominor.yy13.mask = 0xff0000; } -#line 2070 "parse.c" +#line 2071 "parse.c" break; case 71: -#line 294 "parse.y" +#line 296 "parse.y" { yygotominor.yy230 = OE_SetNull; } -#line 2075 "parse.c" +#line 2076 "parse.c" break; case 72: -#line 295 "parse.y" +#line 297 "parse.y" { yygotominor.yy230 = OE_SetDflt; } -#line 2080 "parse.c" +#line 2081 "parse.c" break; case 73: -#line 296 "parse.y" +#line 298 "parse.y" { yygotominor.yy230 = OE_Cascade; } -#line 2085 "parse.c" +#line 2086 "parse.c" break; case 74: -#line 297 "parse.y" +#line 299 "parse.y" { yygotominor.yy230 = OE_Restrict; } -#line 2090 "parse.c" +#line 2091 "parse.c" break; case 75: case 76: @@ -2093,97 +2094,97 @@ case 95: case 96: case 167: -#line 299 "parse.y" +#line 301 "parse.y" {yygotominor.yy230 = yymsp[0].minor.yy230;} -#line 2101 "parse.c" +#line 2102 "parse.c" break; case 80: -#line 309 "parse.y" +#line 311 "parse.y" {yygotominor.yy384.n = 0; yygotominor.yy384.z = 0;} -#line 2106 "parse.c" +#line 2107 "parse.c" break; case 81: -#line 310 "parse.y" +#line 312 "parse.y" {yygotominor.yy384 = yymsp[-1].minor.yy0;} -#line 2111 "parse.c" +#line 2112 "parse.c" break; case 86: -#line 316 "parse.y" +#line 318 "parse.y" {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy462,yymsp[0].minor.yy230,yymsp[-2].minor.yy230,0);} -#line 2116 "parse.c" +#line 2117 "parse.c" break; case 87: -#line 318 "parse.y" +#line 320 "parse.y" {sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy462,yymsp[0].minor.yy230,0,0,0,0);} -#line 2121 "parse.c" +#line 2122 "parse.c" break; case 88: -#line 319 "parse.y" +#line 321 "parse.y" {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy178);} -#line 2126 "parse.c" +#line 2127 "parse.c" break; case 89: -#line 321 "parse.y" +#line 323 "parse.y" { sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy462, &yymsp[-3].minor.yy384, yymsp[-2].minor.yy462, yymsp[-1].minor.yy230); sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy230); } -#line 2134 "parse.c" +#line 2135 "parse.c" break; case 92: case 94: -#line 335 "parse.y" +#line 337 "parse.y" {yygotominor.yy230 = OE_Default;} -#line 2140 "parse.c" +#line 2141 "parse.c" break; case 97: -#line 340 "parse.y" +#line 342 "parse.y" {yygotominor.yy230 = OE_Ignore;} -#line 2145 "parse.c" +#line 2146 "parse.c" break; case 98: case 168: -#line 341 "parse.y" +#line 343 "parse.y" {yygotominor.yy230 = OE_Replace;} -#line 2151 "parse.c" +#line 2152 "parse.c" break; case 99: -#line 345 "parse.y" +#line 347 "parse.y" { sqlite3DropTable(pParse, yymsp[0].minor.yy285, 0, yymsp[-1].minor.yy230); } -#line 2158 "parse.c" +#line 2159 "parse.c" break; case 102: -#line 355 "parse.y" +#line 357 "parse.y" { sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy384, &yymsp[-2].minor.yy384, yymsp[0].minor.yy239, yymsp[-5].minor.yy230); } -#line 2165 "parse.c" +#line 2166 "parse.c" break; case 103: -#line 358 "parse.y" +#line 360 "parse.y" { sqlite3DropTable(pParse, yymsp[0].minor.yy285, 1, yymsp[-1].minor.yy230); } -#line 2172 "parse.c" +#line 2173 "parse.c" break; case 104: -#line 365 "parse.y" +#line 367 "parse.y" { sqlite3Select(pParse, yymsp[0].minor.yy239, SRT_Callback, 0, 0, 0, 0, 0); sqlite3SelectDelete(yymsp[0].minor.yy239); } -#line 2180 "parse.c" +#line 2181 "parse.c" break; case 105: case 128: -#line 375 "parse.y" +#line 377 "parse.y" {yygotominor.yy239 = yymsp[0].minor.yy239;} -#line 2186 "parse.c" +#line 2187 "parse.c" break; case 106: -#line 377 "parse.y" +#line 379 "parse.y" { if( yymsp[0].minor.yy239 ){ yymsp[0].minor.yy239->op = yymsp[-1].minor.yy230; @@ -2191,87 +2192,87 @@ } yygotominor.yy239 = yymsp[0].minor.yy239; } -#line 2197 "parse.c" +#line 2198 "parse.c" break; case 108: -#line 386 "parse.y" +#line 388 "parse.y" {yygotominor.yy230 = TK_ALL;} -#line 2202 "parse.c" +#line 2203 "parse.c" break; case 110: -#line 390 "parse.y" +#line 392 "parse.y" { yygotominor.yy239 = sqlite3SelectNew(yymsp[-6].minor.yy462,yymsp[-5].minor.yy285,yymsp[-4].minor.yy178,yymsp[-3].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy462,yymsp[-7].minor.yy230,yymsp[0].minor.yy270.pLimit,yymsp[0].minor.yy270.pOffset); } -#line 2209 "parse.c" +#line 2210 "parse.c" break; case 114: case 235: -#line 411 "parse.y" +#line 413 "parse.y" {yygotominor.yy462 = yymsp[-1].minor.yy462;} -#line 2215 "parse.c" +#line 2216 "parse.c" break; case 115: case 141: case 151: case 234: -#line 412 "parse.y" +#line 414 "parse.y" {yygotominor.yy462 = 0;} -#line 2223 "parse.c" +#line 2224 "parse.c" break; case 116: -#line 413 "parse.y" +#line 415 "parse.y" { yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[-1].minor.yy178,yymsp[0].minor.yy384.n?&yymsp[0].minor.yy384:0); } -#line 2230 "parse.c" +#line 2231 "parse.c" break; case 117: -#line 416 "parse.y" +#line 418 "parse.y" { yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-1].minor.yy462, sqlite3Expr(TK_ALL, 0, 0, 0), 0); } -#line 2237 "parse.c" +#line 2238 "parse.c" break; case 118: -#line 419 "parse.y" +#line 421 "parse.y" { Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384); yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-3].minor.yy462, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); } -#line 2246 "parse.c" +#line 2247 "parse.c" break; case 121: -#line 431 "parse.y" +#line 433 "parse.y" {yygotominor.yy384.n = 0;} -#line 2251 "parse.c" +#line 2252 "parse.c" break; case 122: -#line 443 "parse.y" +#line 445 "parse.y" {yygotominor.yy285 = sqliteMalloc(sizeof(*yygotominor.yy285));} -#line 2256 "parse.c" +#line 2257 "parse.c" break; case 123: -#line 444 "parse.y" +#line 446 "parse.y" {yygotominor.yy285 = yymsp[0].minor.yy285;} -#line 2261 "parse.c" +#line 2262 "parse.c" break; case 124: -#line 449 "parse.y" +#line 451 "parse.y" { yygotominor.yy285 = yymsp[-1].minor.yy285; if( yygotominor.yy285 && yygotominor.yy285->nSrc>0 ) yygotominor.yy285->a[yygotominor.yy285->nSrc-1].jointype = yymsp[0].minor.yy230; } -#line 2269 "parse.c" +#line 2270 "parse.c" break; case 125: -#line 453 "parse.y" +#line 455 "parse.y" {yygotominor.yy285 = 0;} -#line 2274 "parse.c" +#line 2275 "parse.c" break; case 126: -#line 454 "parse.y" +#line 456 "parse.y" { yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-5].minor.yy285,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384); if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384); @@ -2284,10 +2285,10 @@ else { sqlite3IdListDelete(yymsp[0].minor.yy160); } } } -#line 2290 "parse.c" +#line 2291 "parse.c" break; case 127: -#line 468 "parse.y" +#line 470 "parse.y" { yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-6].minor.yy285,0,0); yygotominor.yy285->a[yygotominor.yy285->nSrc-1].pSelect = yymsp[-4].minor.yy239; @@ -2301,44 +2302,44 @@ else { sqlite3IdListDelete(yymsp[0].minor.yy160); } } } -#line 2307 "parse.c" +#line 2308 "parse.c" break; case 129: -#line 489 "parse.y" +#line 491 "parse.y" { yygotominor.yy239 = sqlite3SelectNew(0,yymsp[0].minor.yy285,0,0,0,0,0,0,0); } -#line 2314 "parse.c" +#line 2315 "parse.c" break; case 130: -#line 495 "parse.y" +#line 497 "parse.y" {yygotominor.yy384.z=0; yygotominor.yy384.n=0;} -#line 2319 "parse.c" +#line 2320 "parse.c" break; case 132: -#line 500 "parse.y" +#line 502 "parse.y" {yygotominor.yy285 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384);} -#line 2324 "parse.c" +#line 2325 "parse.c" break; case 133: -#line 504 "parse.y" +#line 506 "parse.y" { yygotominor.yy230 = JT_INNER; } -#line 2329 "parse.c" +#line 2330 "parse.c" break; case 134: -#line 505 "parse.y" +#line 507 "parse.y" { yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } -#line 2334 "parse.c" +#line 2335 "parse.c" break; case 135: -#line 506 "parse.y" +#line 508 "parse.y" { yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy384,0); } -#line 2339 "parse.c" +#line 2340 "parse.c" break; case 136: -#line 508 "parse.y" +#line 510 "parse.y" { yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy384,&yymsp[-1].minor.yy384); } -#line 2344 "parse.c" +#line 2345 "parse.c" break; case 137: case 145: @@ -2349,9 +2350,9 @@ case 223: case 225: case 229: -#line 512 "parse.y" +#line 514 "parse.y" {yygotominor.yy178 = yymsp[0].minor.yy178;} -#line 2357 "parse.c" +#line 2358 "parse.c" break; case 138: case 153: @@ -2360,161 +2361,161 @@ case 224: case 226: case 230: -#line 513 "parse.y" +#line 515 "parse.y" {yygotominor.yy178 = 0;} -#line 2368 "parse.c" +#line 2369 "parse.c" break; case 139: case 172: -#line 517 "parse.y" +#line 519 "parse.y" {yygotominor.yy160 = yymsp[-1].minor.yy160;} -#line 2374 "parse.c" +#line 2375 "parse.c" break; case 140: case 171: -#line 518 "parse.y" +#line 520 "parse.y" {yygotominor.yy160 = 0;} -#line 2380 "parse.c" +#line 2381 "parse.c" break; case 142: case 152: -#line 529 "parse.y" +#line 531 "parse.y" {yygotominor.yy462 = yymsp[0].minor.yy462;} -#line 2386 "parse.c" +#line 2387 "parse.c" break; case 143: -#line 530 "parse.y" +#line 532 "parse.y" { yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0); if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230; } -#line 2394 "parse.c" +#line 2395 "parse.c" break; case 144: -#line 534 "parse.y" +#line 536 "parse.y" { yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0); if( yygotominor.yy462 && yygotominor.yy462->a ) yygotominor.yy462->a[0].sortOrder = yymsp[0].minor.yy230; } -#line 2402 "parse.c" +#line 2403 "parse.c" break; case 146: case 148: -#line 543 "parse.y" +#line 545 "parse.y" {yygotominor.yy230 = SQLITE_SO_ASC;} -#line 2408 "parse.c" +#line 2409 "parse.c" break; case 147: -#line 544 "parse.y" +#line 546 "parse.y" {yygotominor.yy230 = SQLITE_SO_DESC;} -#line 2413 "parse.c" +#line 2414 "parse.c" break; case 149: -#line 546 "parse.y" +#line 548 "parse.y" {yygotominor.yy384.z = 0; yygotominor.yy384.n = 0;} -#line 2418 "parse.c" +#line 2419 "parse.c" break; case 155: -#line 564 "parse.y" +#line 566 "parse.y" {yygotominor.yy270.pLimit = 0; yygotominor.yy270.pOffset = 0;} -#line 2423 "parse.c" +#line 2424 "parse.c" break; case 156: -#line 565 "parse.y" +#line 567 "parse.y" {yygotominor.yy270.pLimit = yymsp[0].minor.yy178; yygotominor.yy270.pOffset = 0;} -#line 2428 "parse.c" +#line 2429 "parse.c" break; case 157: -#line 567 "parse.y" +#line 569 "parse.y" {yygotominor.yy270.pLimit = yymsp[-2].minor.yy178; yygotominor.yy270.pOffset = yymsp[0].minor.yy178;} -#line 2433 "parse.c" +#line 2434 "parse.c" break; case 158: -#line 569 "parse.y" +#line 571 "parse.y" {yygotominor.yy270.pOffset = yymsp[-2].minor.yy178; yygotominor.yy270.pLimit = yymsp[0].minor.yy178;} -#line 2438 "parse.c" +#line 2439 "parse.c" break; case 159: -#line 573 "parse.y" +#line 575 "parse.y" {sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy285,yymsp[0].minor.yy178);} -#line 2443 "parse.c" +#line 2444 "parse.c" break; case 162: -#line 584 "parse.y" +#line 586 "parse.y" {sqlite3Update(pParse,yymsp[-3].minor.yy285,yymsp[-1].minor.yy462,yymsp[0].minor.yy178,yymsp[-4].minor.yy230);} -#line 2448 "parse.c" +#line 2449 "parse.c" break; case 163: -#line 590 "parse.y" +#line 592 "parse.y" {yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);} -#line 2453 "parse.c" +#line 2454 "parse.c" break; case 164: -#line 591 "parse.y" +#line 593 "parse.y" {yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);} -#line 2458 "parse.c" +#line 2459 "parse.c" break; case 165: -#line 597 "parse.y" +#line 599 "parse.y" {sqlite3Insert(pParse, yymsp[-5].minor.yy285, yymsp[-1].minor.yy462, 0, yymsp[-4].minor.yy160, yymsp[-7].minor.yy230);} -#line 2463 "parse.c" +#line 2464 "parse.c" break; case 166: -#line 599 "parse.y" +#line 601 "parse.y" {sqlite3Insert(pParse, yymsp[-2].minor.yy285, 0, yymsp[0].minor.yy239, yymsp[-1].minor.yy160, yymsp[-4].minor.yy230);} -#line 2468 "parse.c" +#line 2469 "parse.c" break; case 169: case 227: -#line 609 "parse.y" +#line 611 "parse.y" {yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[0].minor.yy178,0);} -#line 2474 "parse.c" +#line 2475 "parse.c" break; case 170: case 228: -#line 610 "parse.y" +#line 612 "parse.y" {yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,0);} -#line 2480 "parse.c" +#line 2481 "parse.c" break; case 173: -#line 619 "parse.y" +#line 621 "parse.y" {yygotominor.yy160 = sqlite3IdListAppend(yymsp[-2].minor.yy160,&yymsp[0].minor.yy384);} -#line 2485 "parse.c" +#line 2486 "parse.c" break; case 174: -#line 620 "parse.y" +#line 622 "parse.y" {yygotominor.yy160 = sqlite3IdListAppend(0,&yymsp[0].minor.yy384);} -#line 2490 "parse.c" +#line 2491 "parse.c" break; case 176: -#line 631 "parse.y" +#line 633 "parse.y" {yygotominor.yy178 = yymsp[-1].minor.yy178; sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2495 "parse.c" +#line 2496 "parse.c" break; case 177: case 182: case 183: -#line 632 "parse.y" +#line 634 "parse.y" {yygotominor.yy178 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2502 "parse.c" +#line 2503 "parse.c" break; case 178: case 179: -#line 633 "parse.y" +#line 635 "parse.y" {yygotominor.yy178 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2508 "parse.c" +#line 2509 "parse.c" break; case 180: -#line 635 "parse.y" +#line 637 "parse.y" { Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384); Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384); yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp2, 0); } -#line 2517 "parse.c" +#line 2518 "parse.c" break; case 181: -#line 640 "parse.y" +#line 642 "parse.y" { Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy384); Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384); @@ -2522,32 +2523,32 @@ Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp4, 0); } -#line 2528 "parse.c" +#line 2529 "parse.c" break; case 184: -#line 649 "parse.y" +#line 651 "parse.y" {yygotominor.yy178 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} -#line 2533 "parse.c" +#line 2534 "parse.c" break; case 185: -#line 650 "parse.y" +#line 652 "parse.y" { Token *pToken = &yymsp[0].minor.yy0; Expr *pExpr = yygotominor.yy178 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } -#line 2542 "parse.c" +#line 2543 "parse.c" break; case 186: -#line 656 "parse.y" +#line 658 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy178, 0, &yymsp[-1].minor.yy384); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); } -#line 2550 "parse.c" +#line 2551 "parse.c" break; case 187: -#line 661 "parse.y" +#line 663 "parse.y" { yygotominor.yy178 = sqlite3ExprFunction(yymsp[-1].minor.yy462, &yymsp[-4].minor.yy0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); @@ -2555,25 +2556,25 @@ yygotominor.yy178->flags |= EP_Distinct; } } -#line 2561 "parse.c" +#line 2562 "parse.c" break; case 188: -#line 668 "parse.y" +#line 670 "parse.y" { yygotominor.yy178 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2569 "parse.c" +#line 2570 "parse.c" break; case 189: -#line 672 "parse.y" +#line 674 "parse.y" { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ yygotominor.yy178 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0); if( yygotominor.yy178 ) yygotominor.yy178->op = TK_CONST_FUNC; } -#line 2579 "parse.c" +#line 2580 "parse.c" break; case 190: case 191: @@ -2583,22 +2584,22 @@ case 195: case 196: case 197: -#line 678 "parse.y" +#line 680 "parse.y" {yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy178, yymsp[0].minor.yy178, 0);} -#line 2591 "parse.c" +#line 2592 "parse.c" break; case 198: -#line 688 "parse.y" +#line 690 "parse.y" {yygotominor.yy440.eOperator = yymsp[0].minor.yy0; yygotominor.yy440.not = 0;} -#line 2596 "parse.c" +#line 2597 "parse.c" break; case 199: -#line 689 "parse.y" +#line 691 "parse.y" {yygotominor.yy440.eOperator = yymsp[0].minor.yy0; yygotominor.yy440.not = 1;} -#line 2601 "parse.c" +#line 2602 "parse.c" break; case 202: -#line 694 "parse.y" +#line 696 "parse.y" { ExprList *pList; pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy178, 0); @@ -2610,66 +2611,66 @@ if( yymsp[-2].minor.yy440.not ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy178->span, &yymsp[-1].minor.yy178->span); } -#line 2616 "parse.c" +#line 2617 "parse.c" break; case 203: -#line 706 "parse.y" +#line 708 "parse.y" { yygotominor.yy178 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy178->span,&yymsp[0].minor.yy0); } -#line 2624 "parse.c" +#line 2625 "parse.c" break; case 204: -#line 710 "parse.y" +#line 712 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0); } -#line 2632 "parse.c" +#line 2633 "parse.c" break; case 205: -#line 714 "parse.y" +#line 716 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0); } -#line 2640 "parse.c" +#line 2641 "parse.c" break; case 206: -#line 718 "parse.y" +#line 720 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,&yymsp[0].minor.yy0); } -#line 2648 "parse.c" +#line 2649 "parse.c" break; case 207: -#line 722 "parse.y" +#line 724 "parse.y" { yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span); } -#line 2656 "parse.c" +#line 2657 "parse.c" break; case 208: -#line 726 "parse.y" +#line 728 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span); } -#line 2664 "parse.c" +#line 2665 "parse.c" break; case 209: -#line 730 "parse.y" +#line 732 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span); } -#line 2672 "parse.c" +#line 2673 "parse.c" break; case 212: -#line 737 "parse.y" +#line 739 "parse.y" { ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0); pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0); @@ -2682,10 +2683,10 @@ if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy178->span); } -#line 2688 "parse.c" +#line 2689 "parse.c" break; case 215: -#line 753 "parse.y" +#line 755 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0); if( yygotominor.yy178 ){ @@ -2696,10 +2697,10 @@ if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0); } -#line 2702 "parse.c" +#line 2703 "parse.c" break; case 216: -#line 763 "parse.y" +#line 765 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_SELECT, 0, 0, 0); if( yygotominor.yy178 ){ @@ -2709,10 +2710,10 @@ } sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2715 "parse.c" +#line 2716 "parse.c" break; case 217: -#line 772 "parse.y" +#line 774 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0); if( yygotominor.yy178 ){ @@ -2723,10 +2724,10 @@ if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0); } -#line 2729 "parse.c" +#line 2730 "parse.c" break; case 218: -#line 782 "parse.y" +#line 784 "parse.y" { SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384); yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy178, 0, 0); @@ -2738,10 +2739,10 @@ if( yymsp[-2].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,yymsp[0].minor.yy384.z?&yymsp[0].minor.yy384:&yymsp[-1].minor.yy384); } -#line 2744 "parse.c" +#line 2745 "parse.c" break; case 219: -#line 793 "parse.y" +#line 795 "parse.y" { Expr *p = yygotominor.yy178 = sqlite3Expr(TK_EXISTS, 0, 0, 0); if( p ){ @@ -2751,10 +2752,10 @@ sqlite3SelectDelete(yymsp[-1].minor.yy239); } } -#line 2757 "parse.c" +#line 2758 "parse.c" break; case 220: -#line 805 "parse.y" +#line 807 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, 0); if( yygotominor.yy178 ){ @@ -2764,45 +2765,45 @@ } sqlite3ExprSpan(yygotominor.yy178, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); } -#line 2770 "parse.c" +#line 2771 "parse.c" break; case 221: -#line 816 "parse.y" +#line 818 "parse.y" { yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, yymsp[-2].minor.yy178, 0); yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0); } -#line 2778 "parse.c" +#line 2779 "parse.c" break; case 222: -#line 820 "parse.y" +#line 822 "parse.y" { yygotominor.yy462 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0); yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0); } -#line 2786 "parse.c" +#line 2787 "parse.c" break; case 231: -#line 847 "parse.y" +#line 849 "parse.y" { sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy384, &yymsp[-5].minor.yy384, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy384,0), yymsp[-1].minor.yy462, yymsp[-9].minor.yy230, &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy230); } -#line 2794 "parse.c" +#line 2795 "parse.c" break; case 232: case 277: -#line 853 "parse.y" +#line 855 "parse.y" {yygotominor.yy230 = OE_Abort;} -#line 2800 "parse.c" +#line 2801 "parse.c" break; case 233: -#line 854 "parse.y" +#line 856 "parse.y" {yygotominor.yy230 = OE_None;} -#line 2805 "parse.c" +#line 2806 "parse.c" break; case 236: -#line 864 "parse.y" +#line 866 "parse.y" { Expr *p = 0; if( yymsp[-1].minor.yy384.n>0 ){ @@ -2812,10 +2813,10 @@ yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, p, &yymsp[-2].minor.yy384); if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230; } -#line 2818 "parse.c" +#line 2819 "parse.c" break; case 237: -#line 873 "parse.y" +#line 875 "parse.y" { Expr *p = 0; if( yymsp[-1].minor.yy384.n>0 ){ @@ -2825,115 +2826,115 @@ yygotominor.yy462 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy384); if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230; } -#line 2831 "parse.c" +#line 2832 "parse.c" break; case 239: -#line 887 "parse.y" +#line 889 "parse.y" {sqlite3DropIndex(pParse, yymsp[0].minor.yy285, yymsp[-1].minor.yy230);} -#line 2836 "parse.c" +#line 2837 "parse.c" break; case 240: case 241: -#line 891 "parse.y" +#line 893 "parse.y" {sqlite3Vacuum(pParse);} -#line 2842 "parse.c" +#line 2843 "parse.c" break; case 242: case 244: -#line 897 "parse.y" +#line 899 "parse.y" {sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,0);} -#line 2848 "parse.c" +#line 2849 "parse.c" break; case 243: -#line 898 "parse.y" +#line 900 "parse.y" {sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy0,0);} -#line 2853 "parse.c" +#line 2854 "parse.c" break; case 245: -#line 900 "parse.y" +#line 902 "parse.y" { sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,1); } -#line 2860 "parse.c" +#line 2861 "parse.c" break; case 246: -#line 903 "parse.y" +#line 905 "parse.y" {sqlite3Pragma(pParse,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384,&yymsp[-1].minor.yy384,0);} -#line 2865 "parse.c" +#line 2866 "parse.c" break; case 247: -#line 904 "parse.y" +#line 906 "parse.y" {sqlite3Pragma(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,0,0);} -#line 2870 "parse.c" +#line 2871 "parse.c" break; case 253: -#line 916 "parse.y" +#line 918 "parse.y" { Token all; all.z = yymsp[-3].minor.yy384.z; all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy384.z) + yymsp[0].minor.yy0.n; sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy247, &all); } -#line 2880 "parse.c" +#line 2881 "parse.c" break; case 254: -#line 925 "parse.y" +#line 927 "parse.y" { sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy384, &yymsp[-6].minor.yy384, yymsp[-5].minor.yy230, yymsp[-4].minor.yy132.a, yymsp[-4].minor.yy132.b, yymsp[-2].minor.yy285, yymsp[-1].minor.yy230, yymsp[0].minor.yy178, yymsp[-9].minor.yy230); yygotominor.yy384 = (yymsp[-6].minor.yy384.n==0?yymsp[-7].minor.yy384:yymsp[-6].minor.yy384); } -#line 2888 "parse.c" +#line 2889 "parse.c" break; case 255: case 258: -#line 931 "parse.y" +#line 933 "parse.y" { yygotominor.yy230 = TK_BEFORE; } -#line 2894 "parse.c" +#line 2895 "parse.c" break; case 256: -#line 932 "parse.y" +#line 934 "parse.y" { yygotominor.yy230 = TK_AFTER; } -#line 2899 "parse.c" +#line 2900 "parse.c" break; case 257: -#line 933 "parse.y" +#line 935 "parse.y" { yygotominor.yy230 = TK_INSTEAD;} -#line 2904 "parse.c" +#line 2905 "parse.c" break; case 259: case 260: -#line 938 "parse.y" +#line 940 "parse.y" {yygotominor.yy132.a = yymsp[0].major; yygotominor.yy132.b = 0;} -#line 2910 "parse.c" +#line 2911 "parse.c" break; case 261: -#line 940 "parse.y" +#line 942 "parse.y" {yygotominor.yy132.a = TK_UPDATE; yygotominor.yy132.b = yymsp[0].minor.yy160;} -#line 2915 "parse.c" +#line 2916 "parse.c" break; case 262: case 263: -#line 943 "parse.y" +#line 945 "parse.y" { yygotominor.yy230 = TK_ROW; } -#line 2921 "parse.c" +#line 2922 "parse.c" break; case 264: -#line 945 "parse.y" +#line 947 "parse.y" { yygotominor.yy230 = TK_STATEMENT; } -#line 2926 "parse.c" +#line 2927 "parse.c" break; case 265: -#line 949 "parse.y" +#line 951 "parse.y" { yygotominor.yy178 = 0; } -#line 2931 "parse.c" +#line 2932 "parse.c" break; case 266: -#line 950 "parse.y" +#line 952 "parse.y" { yygotominor.yy178 = yymsp[0].minor.yy178; } -#line 2936 "parse.c" +#line 2937 "parse.c" break; case 267: -#line 954 "parse.y" +#line 956 "parse.y" { if( yymsp[-2].minor.yy247 ){ yymsp[-2].minor.yy247->pLast->pNext = yymsp[-1].minor.yy247; @@ -2943,40 +2944,40 @@ yymsp[-2].minor.yy247->pLast = yymsp[-1].minor.yy247; yygotominor.yy247 = yymsp[-2].minor.yy247; } -#line 2949 "parse.c" +#line 2950 "parse.c" break; case 268: -#line 963 "parse.y" +#line 965 "parse.y" { yygotominor.yy247 = 0; } -#line 2954 "parse.c" +#line 2955 "parse.c" break; case 269: -#line 969 "parse.y" +#line 971 "parse.y" { yygotominor.yy247 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy384, yymsp[-1].minor.yy462, yymsp[0].minor.yy178, yymsp[-4].minor.yy230); } -#line 2959 "parse.c" +#line 2960 "parse.c" break; case 270: -#line 974 "parse.y" +#line 976 "parse.y" {yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy384, yymsp[-4].minor.yy160, yymsp[-1].minor.yy462, 0, yymsp[-7].minor.yy230);} -#line 2964 "parse.c" +#line 2965 "parse.c" break; case 271: -#line 977 "parse.y" +#line 979 "parse.y" {yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy384, yymsp[-1].minor.yy160, 0, yymsp[0].minor.yy239, yymsp[-4].minor.yy230);} -#line 2969 "parse.c" +#line 2970 "parse.c" break; case 272: -#line 981 "parse.y" +#line 983 "parse.y" {yygotominor.yy247 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy384, yymsp[0].minor.yy178);} -#line 2974 "parse.c" +#line 2975 "parse.c" break; case 273: -#line 984 "parse.y" +#line 986 "parse.y" {yygotominor.yy247 = sqlite3TriggerSelectStep(yymsp[0].minor.yy239); } -#line 2979 "parse.c" +#line 2980 "parse.c" break; case 274: -#line 987 "parse.y" +#line 989 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, 0); if( yygotominor.yy178 ){ @@ -2984,10 +2985,10 @@ sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); } } -#line 2990 "parse.c" +#line 2991 "parse.c" break; case 275: -#line 994 "parse.y" +#line 996 "parse.y" { yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy384); if( yygotominor.yy178 ) { @@ -2995,89 +2996,89 @@ sqlite3ExprSpan(yygotominor.yy178, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); } } -#line 3001 "parse.c" +#line 3002 "parse.c" break; case 276: -#line 1004 "parse.y" +#line 1006 "parse.y" {yygotominor.yy230 = OE_Rollback;} -#line 3006 "parse.c" +#line 3007 "parse.c" break; case 278: -#line 1006 "parse.y" +#line 1008 "parse.y" {yygotominor.yy230 = OE_Fail;} -#line 3011 "parse.c" +#line 3012 "parse.c" break; case 279: -#line 1011 "parse.y" +#line 1013 "parse.y" { sqlite3DropTrigger(pParse,yymsp[0].minor.yy285); } -#line 3018 "parse.c" +#line 3019 "parse.c" break; case 280: -#line 1017 "parse.y" +#line 1019 "parse.y" { sqlite3Attach(pParse, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, yymsp[0].minor.yy292); } -#line 3025 "parse.c" +#line 3026 "parse.c" break; case 281: -#line 1022 "parse.y" +#line 1024 "parse.y" { yygotominor.yy292 = 0; } -#line 3030 "parse.c" +#line 3031 "parse.c" break; case 282: -#line 1023 "parse.y" +#line 1025 "parse.y" { yygotominor.yy292 = yymsp[0].minor.yy178; } -#line 3035 "parse.c" +#line 3036 "parse.c" break; case 285: -#line 1029 "parse.y" +#line 1031 "parse.y" { sqlite3Detach(pParse, yymsp[0].minor.yy178); } -#line 3042 "parse.c" +#line 3043 "parse.c" break; case 286: -#line 1035 "parse.y" +#line 1037 "parse.y" {sqlite3Reindex(pParse, 0, 0);} -#line 3047 "parse.c" +#line 3048 "parse.c" break; case 287: -#line 1036 "parse.y" +#line 1038 "parse.y" {sqlite3Reindex(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);} -#line 3052 "parse.c" +#line 3053 "parse.c" break; case 288: -#line 1041 "parse.y" +#line 1043 "parse.y" {sqlite3Analyze(pParse, 0, 0);} -#line 3057 "parse.c" +#line 3058 "parse.c" break; case 289: -#line 1042 "parse.y" +#line 1044 "parse.y" {sqlite3Analyze(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);} -#line 3062 "parse.c" +#line 3063 "parse.c" break; case 290: -#line 1047 "parse.y" +#line 1049 "parse.y" { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy285,&yymsp[0].minor.yy384); } -#line 3069 "parse.c" +#line 3070 "parse.c" break; case 291: -#line 1050 "parse.y" +#line 1052 "parse.y" { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy384); } -#line 3076 "parse.c" +#line 3077 "parse.c" break; case 292: -#line 1053 "parse.y" +#line 1055 "parse.y" { sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy285); } -#line 3083 "parse.c" +#line 3084 "parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -3136,14 +3137,15 @@ #define TOKEN (yyminor.yy0) #line 34 "parse.y" - if( pParse->zErrMsg==0 ){ + if( !pParse->parseError ){ if( TOKEN.z[0] ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); }else{ sqlite3ErrorMsg(pParse, "incomplete SQL statement"); } + pParse->parseError = 1; } -#line 3150 "parse.c" +#line 3152 "parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } @@ -3271,7 +3273,9 @@ while( yypParser->yyidx >= 0 && yymx != YYERRORSYMBOL && - (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE ){ yy_pop_parser_stack(yypParser); } ============================================================ --- sqlite/prepare.c 6afd730cc8851c0920b5f9050294646b1c2ab28c +++ sqlite/prepare.c bbf12d3147116b284b157232efaef3bbe5df08fc @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.33 2006/03/13 15:06:07 drh Exp $ +** $Id: prepare.c,v 1.34 2006/05/23 23:22:29 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -211,7 +211,7 @@ ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. - ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE + ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE ** meta[5] The user cookie. Used by the application. ** meta[6] ** meta[7] ============================================================ --- sqlite/printf.c 358b4b585270f92a228e646e7bbb261c65f2a166 +++ sqlite/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240 @@ -333,6 +333,8 @@ infop = &fmtinfo[idx]; if( useExtended || (infop->flags & FLAG_INTERN)==0 ){ xtype = infop->type; + }else{ + return -1; } break; } ============================================================ --- sqlite/select.c ca8ee9b54a52e31c22c23ae5264d323f723d253b +++ sqlite/select.c 8daba07a04a6d41f5267ea8353324cbe5a210e14 @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.310 2006/03/26 01:21:23 drh Exp $ +** $Id: select.c,v 1.313 2006/04/26 17:39:34 drh Exp $ */ #include "sqliteInt.h" @@ -805,6 +805,7 @@ assert( pExpr->op!=TK_AS ); switch( pExpr->op ){ + case TK_AGG_COLUMN: case TK_COLUMN: { /* The expression is a column. Locate the table the column is being ** extracted from in NameContext.pSrcList. This table may be real @@ -2485,11 +2486,6 @@ if( sqlite3ExprResolveNames(pNC, pE) ){ return 1; } - if( sqlite3ExprIsConstant(pE) ){ - sqlite3ErrorMsg(pParse, - "%s BY terms must not be non-integer constants", zType); - return 1; - } } return 0; } @@ -2936,17 +2932,17 @@ addrSortIndex = -1; } - /* Set the limiter. - */ - iEnd = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iEnd); - /* If the output is destined for a temporary table, open that table. */ if( eDest==SRT_VirtualTab ){ sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, pEList->nExpr); } + /* Set the limiter. + */ + iEnd = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, iEnd); + /* Open a virtual index to use for the distinct set. */ if( isDistinct ){ ============================================================ --- sqlite/sqlite3.h 8fce4dddf986e8bca2236a84423b2ba4a4ff4bd1 +++ sqlite/sqlite3.h de25268fd9fbc74cf0a7c2e07d455e022cc27daf @@ -31,7 +31,7 @@ #ifdef SQLITE_VERSION # undef SQLITE_VERSION #endif -#define SQLITE_VERSION "3.3.5" +#define SQLITE_VERSION "3.3.6" /* ** The format of the version string is "X.Y.Z", where @@ -48,7 +48,7 @@ #ifdef SQLITE_VERSION_NUMBER # undef SQLITE_VERSION_NUMBER #endif -#define SQLITE_VERSION_NUMBER 3003005 +#define SQLITE_VERSION_NUMBER 3003006 /* ** The version string is also compiled into the library so that a program ============================================================ --- sqlite/sqliteInt.h 9052a26e0467be0ac0c554fb1f8de671eda2ea0d +++ sqlite/sqliteInt.h 96bd4e89dc78164647382890e39aae0e7e05c9d6 @@ -11,11 +11,13 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.493 2006/04/04 01:54:55 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.494 2006/05/25 12:17:31 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ +#include "config.h" + /* ** Extra interface definitions for those who need them */ @@ -1237,6 +1239,7 @@ u8 nameClash; /* A permanent table name clashes with temp table name */ u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ + u8 parseError; /* True if a parsing error has been seen */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ ============================================================ --- sqlite/utf.c 1d51225bce1ea8d1978e8ab28e862a0c12c7a8e8 +++ sqlite/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44 @@ -12,7 +12,7 @@ ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.38 2006/02/24 02:53:50 drh Exp $ +** $Id: utf.c,v 1.39 2006/04/16 12:05:03 drh Exp $ ** ** Notes on UTF-8: ** @@ -287,11 +287,11 @@ /* Set len to the maximum number of bytes required in the output buffer. */ if( desiredEnc==SQLITE_UTF8 ){ /* When converting from UTF-16, the maximum growth results from - ** translating a 2-byte character to a 3-byte UTF-8 character (i.e. - ** code-point 0xFFFC). A single byte is required for the output string + ** translating a 2-byte character to a 4-byte UTF-8 character. + ** A single byte is required for the output string ** nul-terminator. */ - len = (pMem->n/2) * 3 + 1; + len = pMem->n * 2 + 1; }else{ /* When converting from UTF-8 to UTF-16 the maximum growth is caused ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 ============================================================ --- sqlite/util.c 137e6765825863593095cbbeab0e9e4ba1cf575d +++ sqlite/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.188 2006/04/04 01:54:55 drh Exp $ +** $Id: util.c,v 1.189 2006/04/08 19:14:53 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -476,8 +476,9 @@ ** pointer to the space allocated for the application to use. */ static void OSFREE(void *pFree){ + u32 *p; /* Pointer to the OS-layer allocation */ sqlite3OsEnterMutex(); - u32 *p = (u32 *)getOsPointer(pFree); /* p points to Os level allocation */ + p = (u32 *)getOsPointer(pFree); checkGuards(p); unlinkAlloc(p); memset(pFree, 0x55, OSSIZEOF(pFree)); ============================================================ --- sqlite/vdbe.c a56ef5de6d91aedf6f1f0db03c65aa01ecbe11ba +++ sqlite/vdbe.c a4c970bd74a5af20bf4627f704a634ceff8ff68d @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.548 2006/03/22 22:10:08 drh Exp $ +** $Id: vdbe.c,v 1.550 2006/06/03 18:04:17 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -495,11 +495,14 @@ */ if( db->xProgress ){ if( db->nProgressOps==nProgressOps ){ + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; if( db->xProgress(db->pProgressArg)!=0 ){ + sqlite3SafetyOn(db); rc = SQLITE_ABORT; continue; /* skip to the next iteration of the for loop */ } nProgressOps = 0; + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; } nProgressOps++; } ============================================================ --- sqlite/where.c 1ba8eb02aba7eb8b75d7be0635200a14f0bef73a +++ sqlite/where.c 06ec443109d8aec7be6d491ef31f72bc08af2c75 @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.206 2006/03/28 23:55:58 drh Exp $ +** $Id: where.c,v 1.209 2006/06/06 11:45:55 drh Exp $ */ #include "sqliteInt.h" @@ -1034,7 +1034,7 @@ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ - inMultiplier *= 100; + inMultiplier *= 25; }else if( pExpr->pList!=0 ){ inMultiplier *= pExpr->pList->nExpr + 1; } @@ -1224,17 +1224,16 @@ sqlite3CodeSubselect(pParse, pX); iTab = pX->iTable; - sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk); + sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); pLevel->nIn++; sqliteReallocOrFree((void**)&pLevel->aInLoop, - sizeof(pLevel->aInLoop[0])*3*pLevel->nIn); + sizeof(pLevel->aInLoop[0])*2*pLevel->nIn); aIn = pLevel->aInLoop; if( aIn ){ - aIn += pLevel->nIn*3 - 3; - aIn[0] = OP_Next; - aIn[1] = iTab; - aIn[2] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); + aIn += pLevel->nIn*2 - 2; + aIn[0] = iTab; + aIn[1] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); }else{ pLevel->nIn = 0; } @@ -1518,12 +1517,11 @@ lowestCost = SQLITE_BIG_DBL; for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){ - if( once && - ((pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0 - || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0)) - ){ - break; - } + int doNotReorder; /* True if this table should not be reordered */ + + doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0 + || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0); + if( once && doNotReorder ) break; m = getMask(&maskSet, pTabItem->iCursor); if( (m & notReady)==0 ){ if( j==iFrom ) iFrom++; @@ -1540,6 +1538,7 @@ bestNEq = nEq; bestJ = j; } + if( doNotReorder ) break; } TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ, pLevel-pWInfo->a)); @@ -1593,6 +1592,9 @@ }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } + if( pLevel->flags & WHERE_ORDERBY ){ + zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); + } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); } #endif /* SQLITE_OMIT_EXPLAIN */ @@ -2056,8 +2058,9 @@ if( pLevel->nIn ){ int *a; int j; - for(j=pLevel->nIn, a=&pLevel->aInLoop[j*3-3]; j>0; j--, a-=3){ - sqlite3VdbeAddOp(v, a[0], a[1], a[2]); + for(j=pLevel->nIn, a=&pLevel->aInLoop[j*2-2]; j>0; j--, a-=2){ + sqlite3VdbeAddOp(v, OP_Next, a[0], a[1]); + sqlite3VdbeJumpHere(v, a[1]-1); } sqliteFree(pLevel->aInLoop); }